@bsv/sdk 1.1.23 → 1.1.25
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/cjs/package.json +1 -1
- package/dist/cjs/src/primitives/Curve.js +7 -7
- package/dist/cjs/src/primitives/Curve.js.map +1 -1
- package/dist/cjs/src/primitives/ECDSA.js +394 -71
- package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
- package/dist/cjs/src/primitives/Point.js +103 -23
- package/dist/cjs/src/primitives/Point.js.map +1 -1
- package/dist/cjs/src/primitives/TransactionSignature.js +4 -3
- package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/cjs/src/primitives/utils.js +14 -15
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/script/Spend.js +4 -4
- package/dist/cjs/src/script/Spend.js.map +1 -1
- package/dist/cjs/src/totp/totp.js +1 -1
- package/dist/cjs/src/totp/totp.js.map +1 -1
- package/dist/cjs/src/transaction/Beef.js +492 -0
- package/dist/cjs/src/transaction/Beef.js.map +1 -0
- package/dist/cjs/src/transaction/BeefParty.js +97 -0
- package/dist/cjs/src/transaction/BeefParty.js.map +1 -0
- package/dist/cjs/src/transaction/BeefTx.js +123 -0
- package/dist/cjs/src/transaction/BeefTx.js.map +1 -0
- package/dist/cjs/src/transaction/Transaction.js +81 -66
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/src/transaction/index.js +7 -1
- package/dist/cjs/src/transaction/index.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/primitives/Curve.js +7 -7
- package/dist/esm/src/primitives/Curve.js.map +1 -1
- package/dist/esm/src/primitives/ECDSA.js +394 -71
- package/dist/esm/src/primitives/ECDSA.js.map +1 -1
- package/dist/esm/src/primitives/Point.js +103 -23
- package/dist/esm/src/primitives/Point.js.map +1 -1
- package/dist/esm/src/primitives/TransactionSignature.js +4 -3
- package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/esm/src/primitives/utils.js +14 -15
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/script/Spend.js +4 -4
- package/dist/esm/src/script/Spend.js.map +1 -1
- package/dist/esm/src/totp/totp.js +1 -1
- package/dist/esm/src/totp/totp.js.map +1 -1
- package/dist/esm/src/transaction/Beef.js +485 -0
- package/dist/esm/src/transaction/Beef.js.map +1 -0
- package/dist/esm/src/transaction/BeefParty.js +93 -0
- package/dist/esm/src/transaction/BeefParty.js.map +1 -0
- package/dist/esm/src/transaction/BeefTx.js +121 -0
- package/dist/esm/src/transaction/BeefTx.js.map +1 -0
- package/dist/esm/src/transaction/Transaction.js +81 -66
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/src/transaction/index.js +3 -0
- package/dist/esm/src/transaction/index.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
- package/dist/types/src/primitives/Point.d.ts +5 -0
- package/dist/types/src/primitives/Point.d.ts.map +1 -1
- package/dist/types/src/primitives/TransactionSignature.d.ts.map +1 -1
- package/dist/types/src/primitives/utils.d.ts.map +1 -1
- package/dist/types/src/transaction/Beef.d.ts +143 -0
- package/dist/types/src/transaction/Beef.d.ts.map +1 -0
- package/dist/types/src/transaction/BeefParty.d.ts +62 -0
- package/dist/types/src/transaction/BeefParty.d.ts.map +1 -0
- package/dist/types/src/transaction/BeefTx.d.ts +35 -0
- package/dist/types/src/transaction/BeefTx.d.ts.map +1 -0
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/src/transaction/TransactionInput.d.ts +1 -1
- package/dist/types/src/transaction/TransactionInput.d.ts.map +1 -1
- package/dist/types/src/transaction/index.d.ts +3 -0
- package/dist/types/src/transaction/index.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/docs/primitives.md +373 -55
- package/docs/transaction.md +467 -1
- package/package.json +1 -1
- package/src/primitives/Curve.ts +7 -7
- package/src/primitives/ECDSA.ts +485 -75
- package/src/primitives/Point.ts +110 -25
- package/src/primitives/TransactionSignature.ts +4 -3
- package/src/primitives/utils.ts +15 -11
- package/src/script/Spend.ts +4 -4
- package/src/totp/totp.ts +1 -1
- package/src/transaction/Beef.ts +533 -0
- package/src/transaction/BeefParty.ts +100 -0
- package/src/transaction/BeefTx.ts +121 -0
- package/src/transaction/Transaction.ts +95 -69
- package/src/transaction/TransactionInput.ts +1 -1
- package/src/transaction/__tests/Beef.test.ts +290 -0
- package/src/transaction/__tests/Transaction.benchmarks.test.ts +222 -0
- package/src/transaction/index.ts +3 -0
package/docs/primitives.md
CHANGED
|
@@ -5348,6 +5348,7 @@ export default class Point extends BasePoint {
|
|
|
5348
5348
|
inf: boolean;
|
|
5349
5349
|
static fromDER(bytes: number[]): Point
|
|
5350
5350
|
static fromString(str: string): Point
|
|
5351
|
+
static redSqrtOptimized(y2: BigNumber): BigNumber
|
|
5351
5352
|
static fromX(x: BigNumber | number | number[] | string, odd: boolean): Point
|
|
5352
5353
|
static fromJSON(obj: string | any[], isRed: boolean): Point
|
|
5353
5354
|
constructor(x: BigNumber | number | number[] | string | null, y: BigNumber | number | number[] | string | null, isRed: boolean = true)
|
|
@@ -7902,61 +7903,241 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
|
|
|
7902
7903
|
|
|
7903
7904
|
```ts
|
|
7904
7905
|
sign = (msg: BigNumber, key: BigNumber, forceLowS: boolean = false, customK?: BigNumber | Function): Signature => {
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7906
|
+
if (typeof BigInt === "function") {
|
|
7907
|
+
const zero = BigInt(0);
|
|
7908
|
+
const one = BigInt(1);
|
|
7909
|
+
const two = BigInt(2);
|
|
7910
|
+
const n = BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
|
|
7911
|
+
const p = BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");
|
|
7912
|
+
const Gx = BigInt("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798");
|
|
7913
|
+
const Gy = BigInt("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
|
|
7914
|
+
const G = { x: Gx, y: Gy };
|
|
7915
|
+
const z = BigInt("0x" + msg.toString(16));
|
|
7916
|
+
const d = BigInt("0x" + key.toString(16));
|
|
7917
|
+
if (d <= zero || d >= n) {
|
|
7918
|
+
throw new Error("Invalid private key");
|
|
7919
|
+
}
|
|
7920
|
+
function bigIntToBytes(value: bigint, length: number): Uint8Array {
|
|
7921
|
+
const hex = value.toString(16).padStart(length * 2, "0");
|
|
7922
|
+
const bytes = new Uint8Array(length);
|
|
7923
|
+
for (let i = 0; i < length; i++) {
|
|
7924
|
+
bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
|
|
7925
|
+
}
|
|
7926
|
+
return bytes;
|
|
7927
|
+
}
|
|
7928
|
+
const bytes = 32;
|
|
7929
|
+
const bkey = bigIntToBytes(d, bytes);
|
|
7930
|
+
const nonce = bigIntToBytes(z, bytes);
|
|
7931
|
+
const drbg = new DRBG(Array.from(bkey), Array.from(nonce));
|
|
7932
|
+
const ns1 = n - one;
|
|
7933
|
+
let iter = 0;
|
|
7934
|
+
function truncateToN(k: bigint, n: bigint, truncOnly: boolean = true): bigint {
|
|
7935
|
+
const kBitLength = k.toString(2).length;
|
|
7936
|
+
const nBitLength = n.toString(2).length;
|
|
7937
|
+
const delta = kBitLength - nBitLength;
|
|
7938
|
+
if (delta > 0) {
|
|
7939
|
+
k = k >> BigInt(delta);
|
|
7940
|
+
}
|
|
7941
|
+
if (!truncOnly && k >= n) {
|
|
7942
|
+
return k - n;
|
|
7922
7943
|
}
|
|
7923
7944
|
else {
|
|
7924
|
-
|
|
7945
|
+
return k;
|
|
7925
7946
|
}
|
|
7926
7947
|
}
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7948
|
+
function generateK(): bigint {
|
|
7949
|
+
if (typeof customK === "function") {
|
|
7950
|
+
const k_bn = customK(iter);
|
|
7951
|
+
const k_str = k_bn.toString(16);
|
|
7952
|
+
return BigInt("0x" + k_str);
|
|
7953
|
+
}
|
|
7954
|
+
else if (BigNumber.isBN(customK)) {
|
|
7955
|
+
const k_str = customK.toString(16);
|
|
7956
|
+
return BigInt("0x" + k_str);
|
|
7931
7957
|
}
|
|
7932
7958
|
else {
|
|
7933
|
-
|
|
7959
|
+
const k_hex = drbg.generate(bytes);
|
|
7960
|
+
return BigInt("0x" + k_hex);
|
|
7934
7961
|
}
|
|
7935
7962
|
}
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7963
|
+
function mod(a: bigint, m: bigint): bigint {
|
|
7964
|
+
return ((a % m) + m) % m;
|
|
7965
|
+
}
|
|
7966
|
+
function modInv(a: bigint, m: bigint): bigint {
|
|
7967
|
+
let lm = one;
|
|
7968
|
+
let hm = zero;
|
|
7969
|
+
let low = mod(a, m);
|
|
7970
|
+
let high = m;
|
|
7971
|
+
while (low > one) {
|
|
7972
|
+
const r = high / low;
|
|
7973
|
+
const nm = hm - lm * r;
|
|
7974
|
+
const neww = high - low * r;
|
|
7975
|
+
hm = lm;
|
|
7976
|
+
lm = nm;
|
|
7977
|
+
high = low;
|
|
7978
|
+
low = neww;
|
|
7979
|
+
}
|
|
7980
|
+
return mod(lm, m);
|
|
7981
|
+
}
|
|
7982
|
+
function pointAdd(P: {
|
|
7983
|
+
x: bigint;
|
|
7984
|
+
y: bigint;
|
|
7985
|
+
} | null, Q: {
|
|
7986
|
+
x: bigint;
|
|
7987
|
+
y: bigint;
|
|
7988
|
+
} | null): {
|
|
7989
|
+
x: bigint;
|
|
7990
|
+
y: bigint;
|
|
7991
|
+
} | null {
|
|
7992
|
+
if (P === null)
|
|
7993
|
+
return Q;
|
|
7994
|
+
if (Q === null)
|
|
7995
|
+
return P;
|
|
7996
|
+
if (P.x === Q.x && P.y === mod(-Q.y, p)) {
|
|
7997
|
+
return null;
|
|
7998
|
+
}
|
|
7999
|
+
let m: bigint;
|
|
8000
|
+
if (P.x === Q.x && P.y === Q.y) {
|
|
8001
|
+
if (P.y === zero) {
|
|
8002
|
+
return null;
|
|
8003
|
+
}
|
|
8004
|
+
const numerator = mod(BigInt(3) * P.x * P.x, p);
|
|
8005
|
+
const denominator = modInv(two * P.y, p);
|
|
8006
|
+
m = mod(numerator * denominator, p);
|
|
7941
8007
|
}
|
|
7942
8008
|
else {
|
|
7943
|
-
|
|
8009
|
+
const numerator = mod(Q.y - P.y, p);
|
|
8010
|
+
const denominator = modInv(Q.x - P.x, p);
|
|
8011
|
+
m = mod(numerator * denominator, p);
|
|
7944
8012
|
}
|
|
8013
|
+
const xR = mod(m * m - P.x - Q.x, p);
|
|
8014
|
+
const yR = mod(m * (P.x - xR) - P.y, p);
|
|
8015
|
+
return { x: xR, y: yR };
|
|
7945
8016
|
}
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
8017
|
+
function scalarMul(k: bigint, P: {
|
|
8018
|
+
x: bigint;
|
|
8019
|
+
y: bigint;
|
|
8020
|
+
}): {
|
|
8021
|
+
x: bigint;
|
|
8022
|
+
y: bigint;
|
|
8023
|
+
} | null {
|
|
8024
|
+
let N = P;
|
|
8025
|
+
let Q = null;
|
|
8026
|
+
while (k > zero) {
|
|
8027
|
+
if (k % two === one) {
|
|
8028
|
+
Q = pointAdd(Q, N);
|
|
8029
|
+
}
|
|
8030
|
+
N = pointAdd(N, N);
|
|
8031
|
+
k >>= one;
|
|
7951
8032
|
}
|
|
7952
|
-
|
|
7953
|
-
|
|
8033
|
+
return Q;
|
|
8034
|
+
}
|
|
8035
|
+
while (true) {
|
|
8036
|
+
let k = generateK();
|
|
8037
|
+
iter += 1;
|
|
8038
|
+
k = truncateToN(k, n, true);
|
|
8039
|
+
if (k <= one || k >= ns1) {
|
|
8040
|
+
if (customK instanceof BigNumber) {
|
|
8041
|
+
throw new Error("Invalid fixed custom K value (must be more than 1 and less than N-1)");
|
|
8042
|
+
}
|
|
8043
|
+
else {
|
|
8044
|
+
continue;
|
|
8045
|
+
}
|
|
8046
|
+
}
|
|
8047
|
+
const R = scalarMul(k, G);
|
|
8048
|
+
if (R === null) {
|
|
8049
|
+
if (customK instanceof BigNumber) {
|
|
8050
|
+
throw new Error("Invalid fixed custom K value (must not create a point at infinity when multiplied by the generator point)");
|
|
8051
|
+
}
|
|
8052
|
+
else {
|
|
8053
|
+
continue;
|
|
8054
|
+
}
|
|
8055
|
+
}
|
|
8056
|
+
const r = mod(R.x, n);
|
|
8057
|
+
if (r === zero) {
|
|
8058
|
+
if (customK instanceof BigNumber) {
|
|
8059
|
+
throw new Error("Invalid fixed custom K value (when multiplied by G, the resulting x coordinate mod N must not be zero)");
|
|
8060
|
+
}
|
|
8061
|
+
else {
|
|
8062
|
+
continue;
|
|
8063
|
+
}
|
|
8064
|
+
}
|
|
8065
|
+
const kInv = modInv(k, n);
|
|
8066
|
+
const rd = mod(r * d, n);
|
|
8067
|
+
let s = mod(kInv * (z + rd), n);
|
|
8068
|
+
if (s === zero) {
|
|
8069
|
+
if (customK instanceof BigNumber) {
|
|
8070
|
+
throw new Error("Invalid fixed custom K value (when used with the key, it cannot create a zero value for S)");
|
|
8071
|
+
}
|
|
8072
|
+
else {
|
|
8073
|
+
continue;
|
|
8074
|
+
}
|
|
7954
8075
|
}
|
|
8076
|
+
if (forceLowS && s > n / two) {
|
|
8077
|
+
s = n - s;
|
|
8078
|
+
}
|
|
8079
|
+
const r_bn = new BigNumber(r.toString(16), 16);
|
|
8080
|
+
const s_bn = new BigNumber(s.toString(16), 16);
|
|
8081
|
+
return new Signature(r_bn, s_bn);
|
|
7955
8082
|
}
|
|
7956
|
-
|
|
7957
|
-
|
|
8083
|
+
}
|
|
8084
|
+
else {
|
|
8085
|
+
const curve = new Curve();
|
|
8086
|
+
msg = truncateToN(msg);
|
|
8087
|
+
const bytes = curve.n.byteLength();
|
|
8088
|
+
const bkey = key.toArray("be", bytes);
|
|
8089
|
+
const nonce = msg.toArray("be", bytes);
|
|
8090
|
+
const drbg = new DRBG(bkey, nonce);
|
|
8091
|
+
const ns1 = curve.n.subn(1);
|
|
8092
|
+
for (let iter = 0;; iter++) {
|
|
8093
|
+
let k = typeof customK === "function"
|
|
8094
|
+
? customK(iter)
|
|
8095
|
+
: BigNumber.isBN(customK)
|
|
8096
|
+
? customK
|
|
8097
|
+
: new BigNumber(drbg.generate(bytes), 16);
|
|
8098
|
+
k = truncateToN(k, true);
|
|
8099
|
+
if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0) {
|
|
8100
|
+
if (BigNumber.isBN(customK)) {
|
|
8101
|
+
throw new Error("Invalid fixed custom K value (must be more than 1 and less than N-1)");
|
|
8102
|
+
}
|
|
8103
|
+
else {
|
|
8104
|
+
continue;
|
|
8105
|
+
}
|
|
8106
|
+
}
|
|
8107
|
+
const kp = curve.g.mul(k);
|
|
8108
|
+
if (kp.isInfinity()) {
|
|
8109
|
+
if (BigNumber.isBN(customK)) {
|
|
8110
|
+
throw new Error("Invalid fixed custom K value (must not create a point at infinity when multiplied by the generator point)");
|
|
8111
|
+
}
|
|
8112
|
+
else {
|
|
8113
|
+
continue;
|
|
8114
|
+
}
|
|
8115
|
+
}
|
|
8116
|
+
const kpX = kp.getX();
|
|
8117
|
+
const r = kpX.umod(curve.n);
|
|
8118
|
+
if (r.cmpn(0) === 0) {
|
|
8119
|
+
if (BigNumber.isBN(customK)) {
|
|
8120
|
+
throw new Error("Invalid fixed custom K value (when multiplied by G, the resulting x coordinate mod N must not be zero)");
|
|
8121
|
+
}
|
|
8122
|
+
else {
|
|
8123
|
+
continue;
|
|
8124
|
+
}
|
|
8125
|
+
}
|
|
8126
|
+
let s = k.invm(curve.n).mul(r.mul(key).iadd(msg));
|
|
8127
|
+
s = s.umod(curve.n);
|
|
8128
|
+
if (s.cmpn(0) === 0) {
|
|
8129
|
+
if (BigNumber.isBN(customK)) {
|
|
8130
|
+
throw new Error("Invalid fixed custom K value (when used with the key, it cannot create a zero value for S)");
|
|
8131
|
+
}
|
|
8132
|
+
else {
|
|
8133
|
+
continue;
|
|
8134
|
+
}
|
|
8135
|
+
}
|
|
8136
|
+
if (forceLowS && s.cmp(curve.n.ushrn(1)) > 0) {
|
|
8137
|
+
s = curve.n.sub(s);
|
|
8138
|
+
}
|
|
8139
|
+
return new Signature(r, s);
|
|
7958
8140
|
}
|
|
7959
|
-
return new Signature(r, s);
|
|
7960
8141
|
}
|
|
7961
8142
|
}
|
|
7962
8143
|
```
|
|
@@ -7968,24 +8149,161 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
|
|
|
7968
8149
|
|
|
7969
8150
|
```ts
|
|
7970
8151
|
verify = (msg: BigNumber, sig: Signature, key: Point): boolean => {
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
8152
|
+
if (typeof BigInt === "function") {
|
|
8153
|
+
const zero = BigInt(0);
|
|
8154
|
+
const one = BigInt(1);
|
|
8155
|
+
const two = BigInt(2);
|
|
8156
|
+
const three = BigInt(3);
|
|
8157
|
+
const p = BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");
|
|
8158
|
+
const n = BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
|
|
8159
|
+
const G = {
|
|
8160
|
+
x: BigInt("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"),
|
|
8161
|
+
y: BigInt("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8")
|
|
8162
|
+
};
|
|
8163
|
+
const mod = (a: bigint, m: bigint): bigint => ((a % m) + m) % m;
|
|
8164
|
+
const modInv = (a: bigint, m: bigint): bigint => {
|
|
8165
|
+
let [old_r, r] = [a, m];
|
|
8166
|
+
let [old_s, s] = [BigInt(1), BigInt(0)];
|
|
8167
|
+
while (r !== zero) {
|
|
8168
|
+
const q = old_r / r;
|
|
8169
|
+
[old_r, r] = [r, old_r - q * r];
|
|
8170
|
+
[old_s, s] = [s, old_s - q * s];
|
|
8171
|
+
}
|
|
8172
|
+
if (old_r > one)
|
|
8173
|
+
return zero;
|
|
8174
|
+
return mod(old_s, m);
|
|
8175
|
+
};
|
|
8176
|
+
const modMul = (a: bigint, b: bigint, m: bigint): bigint => mod(a * b, m);
|
|
8177
|
+
const modSub = (a: bigint, b: bigint, m: bigint): bigint => mod(a - b, m);
|
|
8178
|
+
const modAdd = (a: bigint, b: bigint, m: bigint): bigint => mod(a + b, m);
|
|
8179
|
+
const four = BigInt(4);
|
|
8180
|
+
const eight = BigInt(8);
|
|
8181
|
+
interface JacobianPoint {
|
|
8182
|
+
X: bigint;
|
|
8183
|
+
Y: bigint;
|
|
8184
|
+
Z: bigint;
|
|
8185
|
+
}
|
|
8186
|
+
const pointDouble = (P: JacobianPoint): JacobianPoint => {
|
|
8187
|
+
const { X: X1, Y: Y1, Z: Z1 } = P;
|
|
8188
|
+
if (Y1 === zero) {
|
|
8189
|
+
return { X: zero, Y: one, Z: zero };
|
|
8190
|
+
}
|
|
8191
|
+
const Y1_sq = modMul(Y1, Y1, p);
|
|
8192
|
+
const S = modMul(four, modMul(X1, Y1_sq, p), p);
|
|
8193
|
+
const M = modMul(three, modMul(X1, X1, p), p);
|
|
8194
|
+
const X3 = modSub(modMul(M, M, p), modMul(two, S, p), p);
|
|
8195
|
+
const Y3 = modSub(modMul(M, modSub(S, X3, p), p), modMul(eight, modMul(Y1_sq, Y1_sq, p), p), p);
|
|
8196
|
+
const Z3 = modMul(two, modMul(Y1, Z1, p), p);
|
|
8197
|
+
return { X: X3, Y: Y3, Z: Z3 };
|
|
8198
|
+
};
|
|
8199
|
+
const pointAdd = (P: JacobianPoint, Q: JacobianPoint): JacobianPoint => {
|
|
8200
|
+
if (P.Z === zero)
|
|
8201
|
+
return Q;
|
|
8202
|
+
if (Q.Z === zero)
|
|
8203
|
+
return P;
|
|
8204
|
+
const Z1Z1 = modMul(P.Z, P.Z, p);
|
|
8205
|
+
const Z2Z2 = modMul(Q.Z, Q.Z, p);
|
|
8206
|
+
const U1 = modMul(P.X, Z2Z2, p);
|
|
8207
|
+
const U2 = modMul(Q.X, Z1Z1, p);
|
|
8208
|
+
const S1 = modMul(P.Y, modMul(Z2Z2, Q.Z, p), p);
|
|
8209
|
+
const S2 = modMul(Q.Y, modMul(Z1Z1, P.Z, p), p);
|
|
8210
|
+
const H = modSub(U2, U1, p);
|
|
8211
|
+
const r = modSub(S2, S1, p);
|
|
8212
|
+
if (H === zero) {
|
|
8213
|
+
if (r === zero) {
|
|
8214
|
+
return pointDouble(P);
|
|
8215
|
+
}
|
|
8216
|
+
else {
|
|
8217
|
+
return { X: zero, Y: one, Z: zero };
|
|
8218
|
+
}
|
|
8219
|
+
}
|
|
8220
|
+
const HH = modMul(H, H, p);
|
|
8221
|
+
const HHH = modMul(H, HH, p);
|
|
8222
|
+
const V = modMul(U1, HH, p);
|
|
8223
|
+
const X3 = modSub(modSub(modMul(r, r, p), HHH, p), modMul(two, V, p), p);
|
|
8224
|
+
const Y3 = modSub(modMul(r, modSub(V, X3, p), p), modMul(S1, HHH, p), p);
|
|
8225
|
+
const Z3 = modMul(H, modMul(P.Z, Q.Z, p), p);
|
|
8226
|
+
return { X: X3, Y: Y3, Z: Z3 };
|
|
8227
|
+
};
|
|
8228
|
+
const scalarMultiply = (k: bigint, P: {
|
|
8229
|
+
x: bigint;
|
|
8230
|
+
y: bigint;
|
|
8231
|
+
}): JacobianPoint => {
|
|
8232
|
+
const N: JacobianPoint = { X: P.x, Y: P.y, Z: one };
|
|
8233
|
+
let Q: JacobianPoint = { X: zero, Y: one, Z: zero };
|
|
8234
|
+
const kBin = k.toString(2);
|
|
8235
|
+
for (let i = 0; i < kBin.length; i++) {
|
|
8236
|
+
Q = pointDouble(Q);
|
|
8237
|
+
if (kBin[i] === "1") {
|
|
8238
|
+
Q = pointAdd(Q, N);
|
|
8239
|
+
}
|
|
8240
|
+
}
|
|
8241
|
+
return Q;
|
|
8242
|
+
};
|
|
8243
|
+
const verifyECDSA = (hash: bigint, publicKey: {
|
|
8244
|
+
x: bigint;
|
|
8245
|
+
y: bigint;
|
|
8246
|
+
}, signature: {
|
|
8247
|
+
r: bigint;
|
|
8248
|
+
s: bigint;
|
|
8249
|
+
}): boolean => {
|
|
8250
|
+
const { r, s } = signature;
|
|
8251
|
+
const z = hash;
|
|
8252
|
+
if (r <= zero || r >= n || s <= zero || s >= n) {
|
|
8253
|
+
return false;
|
|
8254
|
+
}
|
|
8255
|
+
const w = modInv(s, n);
|
|
8256
|
+
if (w === zero) {
|
|
8257
|
+
return false;
|
|
8258
|
+
}
|
|
8259
|
+
const u1 = modMul(z, w, n);
|
|
8260
|
+
const u2 = modMul(r, w, n);
|
|
8261
|
+
const RG = scalarMultiply(u1, G);
|
|
8262
|
+
const RQ = scalarMultiply(u2, publicKey);
|
|
8263
|
+
const R = pointAdd(RG, RQ);
|
|
8264
|
+
if (R.Z === zero) {
|
|
8265
|
+
return false;
|
|
8266
|
+
}
|
|
8267
|
+
const ZInv = modInv(R.Z, p);
|
|
8268
|
+
if (ZInv === zero) {
|
|
8269
|
+
return false;
|
|
8270
|
+
}
|
|
8271
|
+
const ZInv2 = modMul(ZInv, ZInv, p);
|
|
8272
|
+
const x1_affine = modMul(R.X, ZInv2, p);
|
|
8273
|
+
const v = mod(x1_affine, n);
|
|
8274
|
+
return v === r;
|
|
8275
|
+
};
|
|
8276
|
+
const hash = BigInt("0x" + msg.toString(16));
|
|
8277
|
+
const publicKey = {
|
|
8278
|
+
x: BigInt("0x" + key.x.toString(16)),
|
|
8279
|
+
y: BigInt("0x" + key.y.toString(16))
|
|
8280
|
+
};
|
|
8281
|
+
const signature = {
|
|
8282
|
+
r: BigInt("0x" + sig.r.toString(16)),
|
|
8283
|
+
s: BigInt("0x" + sig.s.toString(16))
|
|
8284
|
+
};
|
|
8285
|
+
return verifyECDSA(hash, publicKey, signature);
|
|
7980
8286
|
}
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
8287
|
+
else {
|
|
8288
|
+
const curve = new Curve();
|
|
8289
|
+
msg = truncateToN(msg);
|
|
8290
|
+
const r = sig.r;
|
|
8291
|
+
const s = sig.s;
|
|
8292
|
+
if (r.cmpn(1) < 0 || r.cmp(curve.n) >= 0) {
|
|
8293
|
+
return false;
|
|
8294
|
+
}
|
|
8295
|
+
if (s.cmpn(1) < 0 || s.cmp(curve.n) >= 0) {
|
|
8296
|
+
return false;
|
|
8297
|
+
}
|
|
8298
|
+
const sinv = s.invm(curve.n);
|
|
8299
|
+
const u1 = sinv.mul(msg).umod(curve.n);
|
|
8300
|
+
const u2 = sinv.mul(r).umod(curve.n);
|
|
8301
|
+
const p = curve.g.jmulAdd(u1, key, u2);
|
|
8302
|
+
if (p.isInfinity()) {
|
|
8303
|
+
return false;
|
|
8304
|
+
}
|
|
8305
|
+
return p.eqXToP(r);
|
|
7987
8306
|
}
|
|
7988
|
-
return p.eqXToP(r);
|
|
7989
8307
|
}
|
|
7990
8308
|
```
|
|
7991
8309
|
|