tbc-lib-js
Advanced tools
Comparing version 1.0.24 to 1.0.25
@@ -24,4 +24,4 @@ const secp256k1 = require("secp256k1"); | ||
* | ||
* @param {Object} bytes | ||
* @returns {BigInt} | ||
* @param {Buffer} buffer | ||
* @returns {BigInt} bigint | ||
*/ | ||
@@ -34,9 +34,9 @@ static intFromBuffer(buffer) { | ||
* | ||
* @param {BigInt} int | ||
* @returns {Buffer} | ||
* @param {BigInt} bigInt | ||
* @returns {Buffer} buffer | ||
*/ | ||
static bufferFromInt(bigInt) { | ||
const buffer = Buffer.alloc(32); // 32 bytes buffer | ||
const numBuffer = Buffer.from(bigInt.toString(16).padStart(64, "0"), "hex"); | ||
numBuffer.copy(buffer, 32 - numBuffer.length); // right align | ||
const numBuf = Buffer.from(bigInt.toString(16).padStart(64, "0"), "hex"); | ||
numBuf.copy(buffer, 32 - numBuf.length); // right align | ||
return buffer; | ||
@@ -49,3 +49,3 @@ } | ||
* @param {Object} obj2 | ||
* @returns {boolean} | ||
* @returns {boolean} true or false | ||
*/ | ||
@@ -66,8 +66,8 @@ static isEqual(obj1, obj2) { | ||
* | ||
* @param {{{x: BigInt, y: BigInt}}} point | ||
* @returns {boolean} | ||
* @param {{x: BigInt, y: BigInt}} point | ||
* @returns {boolean} Is y even? | ||
*/ | ||
static hasEvenY(p) { | ||
if (p === null) throw Error("point is null !"); | ||
return p.y % 2n === 0n; | ||
static hasEvenY(point) { | ||
if (point === null) throw Error("point is null !"); | ||
return point.y % 2n === 0n; | ||
} | ||
@@ -78,3 +78,3 @@ | ||
* @param {BigInt} x | ||
* @returns {[BigInt,]} | ||
* @returns {{x: BigInt, y: BigInt}} point | ||
*/ | ||
@@ -85,3 +85,3 @@ static liftX(x) { | ||
// let y = modSqrt(y_sq, P); | ||
let y = Taproot.modExp(y_sq, (P + 1n) / 4n, P); | ||
let y = this.modExp(y_sq, (P + 1n) / 4n, P); | ||
if (y ** 2n % P !== y_sq) return null; | ||
@@ -93,47 +93,6 @@ return { x, y: y % 2n === 0n ? y : P - y }; | ||
* | ||
* @param {BigInt} a | ||
* @param {BigInt} mod | ||
* @returns {BigInt} | ||
* | ||
*/ | ||
// static modSqrt(a, mod) { | ||
// if (a === 0n) return 0n; | ||
// if (mod === 2n) return a % mod; | ||
// let q = mod - 1n; | ||
// let s = 0n; | ||
// while (q % 2n === 0n) { | ||
// q /= 2n; | ||
// s += 1n; | ||
// } | ||
// let z = 2n; | ||
// while (modExp(z, (mod - 1n) / 2n, mod) === 1n) { | ||
// z += 1n; | ||
// } | ||
// let m = s; | ||
// let c = modExp(z, q, mod); | ||
// let t = modExp(a, q, mod); | ||
// let r = modExp(a, (q + 1n) / 2n, mod); | ||
// while (t !== 0n && t !== 1n) { | ||
// let t2i = t; | ||
// let i = 0n; | ||
// while (t2i !== 1n) { | ||
// t2i = modExp(t2i, 2n, mod); | ||
// i += 1n; | ||
// } | ||
// let b = modExp(c, 2n ** (m - i - 1n), mod); | ||
// m = i; | ||
// c = modExp(b, 2n, mod); | ||
// t = modExp(t, 2n ** i, mod); | ||
// r = modMul(r, b, mod); | ||
// } | ||
// return t === 0n ? null : r; | ||
// } | ||
/** | ||
* | ||
* @param {BigInt} base | ||
* @param {BigInt} exp | ||
* @param {BigInt} mod | ||
* @returns {BigInt} | ||
* @returns {BigInt} exp result | ||
*/ | ||
@@ -145,6 +104,6 @@ static modExp(base, exp, mod) { | ||
if (exp % 2n === 1n) { | ||
res = Taproot.modMul(res, base, mod); | ||
res = this.modMul(res, base, mod); | ||
} | ||
exp = exp / 2n; | ||
base = Taproot.modMul(base, base, mod); | ||
base = this.modMul(base, base, mod); | ||
} | ||
@@ -159,6 +118,6 @@ return res; | ||
* @param {BigInt} mod | ||
* @returns | ||
* @returns mul result | ||
*/ | ||
static modMul(a, b, mod) { | ||
return Taproot.modCheck((a * b) % mod, mod); | ||
return this.modCheck((a * b) % mod, mod); | ||
} | ||
@@ -176,4 +135,4 @@ | ||
} else if (typeof obj === "object") { | ||
const x = Taproot.modCheck(obj.x, mod); | ||
const y = Taproot.modCheck(obj.y, mod); | ||
const x = this.modCheck(obj.x, mod); | ||
const y = this.modCheck(obj.y, mod); | ||
res = { x, y }; | ||
@@ -187,6 +146,6 @@ } else { | ||
/** | ||
* point add static | ||
* point add function | ||
* @param {{x: BigInt, y: BigInt}} p | ||
* @param {{x: BigInt, y: BigInt}} q | ||
* @returns {{x: BigInt, y: BigInt}} | ||
* @returns {{x: BigInt, y: BigInt}} add result | ||
*/ | ||
@@ -199,12 +158,12 @@ static pointAdd(p, q) { | ||
let lam; | ||
if (Taproot.isEqual(p, q)) { | ||
lam = (3n * p.x * p.x * Taproot.modExp(2n * p.y, P - 2n, P)) % P; | ||
if (this.isEqual(p, q)) { | ||
lam = (3n * p.x * p.x * this.modExp(2n * p.y, P - 2n, P)) % P; | ||
} else { | ||
lam = ((q.y - p.y) * Taproot.modExp(q.x - p.x, P - 2n, P)) % P; | ||
lam = ((q.y - p.y) * this.modExp(q.x - p.x, P - 2n, P)) % P; | ||
} | ||
lam = Taproot.modCheck(lam, P); | ||
lam = this.modCheck(lam, P); | ||
const x = (lam * lam - p.x - q.x) % P; | ||
const y = (lam * (p.x - x) - p.y) % P; | ||
return Taproot.modCheck({ x, y }, P); | ||
return this.modCheck({ x, y }, P); | ||
} | ||
@@ -216,3 +175,3 @@ | ||
* @param {BigInt} n | ||
* @returns {{x: BigInt, y: BigInt}} | ||
* @returns {{x: BigInt, y: BigInt}} pointMul result | ||
*/ | ||
@@ -224,6 +183,6 @@ static pointMul(p, n) { | ||
if (n % 2n === 1n) { | ||
res = Taproot.pointAdd(res, temp); | ||
res = this.pointAdd(res, temp); | ||
} | ||
temp = Taproot.pointAdd(temp, temp); | ||
temp = this.pointAdd(temp, temp); | ||
n /= 2n; | ||
@@ -238,3 +197,3 @@ } | ||
* @param {Buffer} msg | ||
* @returns {Buffer} | ||
* @returns {Buffer} taggedHash result | ||
*/ | ||
@@ -251,61 +210,5 @@ static taggedHash(tag, msg) { | ||
* | ||
* @param {Buffer} script | ||
* @returns {Buffer} | ||
* @param {string} wif | ||
* @returns {Buffer} hex format seckey | ||
*/ | ||
static serScript(script) { | ||
// need to achieve | ||
return script; | ||
} | ||
/** | ||
* | ||
* @param {Array} scriptTree | ||
* @returns | ||
*/ | ||
static taprootTreeHelper(scriptTree) { | ||
if (Array.isArray(scriptTree) && scriptTree.length === 2) { | ||
const [left, right] = scriptTree; | ||
let [leftTree, leftHash] = Taproot.taprootTreeHelper(left); | ||
let [rightTree, rightHash] = Taproot.taprootTreeHelper(right); | ||
const combinedTree = [ | ||
...leftTree.map(([leaf, leftConcat]) => [ | ||
leaf, | ||
Buffer.concat([leftConcat, rightHash]), | ||
]), | ||
...rightTree.map(([leaf, rightConcat]) => [ | ||
leaf, | ||
Buffer.concat([rightConcat, leftHash]), | ||
]), | ||
]; | ||
if (leftHash.compare(rightHash) > 0) { | ||
[leftHash, rightHash] = [rightHash, leftHash]; // Swap hashes if needed | ||
} | ||
const branchHash = Taproot.taggedHash( | ||
"TapBranch", | ||
Buffer.concat([leftHash, rightHash]) | ||
); | ||
return [combinedTree, branchHash]; | ||
} else if (Array.isArray(scriptTree) && scriptTree.length === 2) { | ||
// Ensure that the leaf node is also an array with two elements | ||
const [leafVersion, script] = scriptTree; | ||
const scriptBuffer = Taproot.serScript(script); | ||
const leafHash = Taproot.taggedHash( | ||
"TapLeaf", | ||
Buffer.concat([Buffer.from([leafVersion]), scriptBuffer]) | ||
); | ||
// Return a tuple of tree and hash | ||
return [[[leafVersion, script], Buffer.alloc(0)], leafHash]; | ||
} else { | ||
throw new Error("Invalid scriptTree format"); | ||
} | ||
} | ||
/** | ||
* | ||
* @param {String} wif | ||
* @returns {Buffer} | ||
*/ | ||
static wifToSeckey(wif) { | ||
@@ -339,3 +242,3 @@ const decoded = bs58.decode(wif); | ||
* @param {Buffer} seckey | ||
* @returns {String} | ||
* @returns {string} wif format seckey | ||
*/ | ||
@@ -359,3 +262,3 @@ static seckeyToWif(seckey) { | ||
* @param {Buffer} seckey | ||
* @returns {Buffer} | ||
* @returns {Buffer} compressed pubkey | ||
*/ | ||
@@ -366,10 +269,10 @@ static pubkeyGen(seckey) { | ||
} | ||
const d0 = Taproot.intFromBuffer(seckey); | ||
const d0 = this.intFromBuffer(seckey); | ||
if (d0 < 1n || d0 >= N) { | ||
throw Error("The secret key must be an integer in the range 1..n-1."); | ||
} | ||
const p = Taproot.pointMul(G, d0); | ||
const p = this.pointMul(G, d0); | ||
if (p === null) throw Error("The point is null."); | ||
const prefix = Buffer.from(p.y % 2n === 0n ? "\x02" : "\x03"); | ||
return Buffer.concat([prefix, Taproot.bufferFromInt(p.x)]); | ||
return Buffer.concat([prefix, this.bufferFromInt(p.x)]); | ||
} | ||
@@ -380,6 +283,8 @@ | ||
* @param {Buffer} pubkey | ||
* @param {Buffer} h | ||
* @returns {Buffer} | ||
* @returns {Buffer} tapTweakPubkey | ||
*/ | ||
static taprootTweakPubkey(pubkey, h) { | ||
static pubkeyToTaprootTweakPubkey(pubkey) { | ||
let script = ""; | ||
const h = Buffer.from(script, "ascii"); | ||
if (!Buffer.isBuffer(pubkey) || pubkey.length !== 33) { | ||
@@ -389,4 +294,4 @@ throw new Error("Invalid public key: must be a 33-byte Buffer."); | ||
pubkey = Uint8Array.prototype.slice.call(pubkey, 1); | ||
const t = Taproot.intFromBuffer( | ||
Taproot.taggedHash("TapTweak", Buffer.concat([pubkey, h])) | ||
const t = this.intFromBuffer( | ||
this.taggedHash("TapTweak", Buffer.concat([pubkey, h])) | ||
); | ||
@@ -397,3 +302,3 @@ if (t >= N) { | ||
const p = Taproot.liftX(Taproot.intFromBuffer(pubkey)); | ||
const p = this.liftX(this.intFromBuffer(pubkey)); | ||
if (p === null) { | ||
@@ -403,6 +308,6 @@ throw new Error("Invalid public key"); | ||
const q = Taproot.pointAdd(p, Taproot.pointMul(G, t)); | ||
// const prefix = Buffer.from(q.y % 2n === 0n ? "\x02" : "\x03"); | ||
const q = this.pointAdd(p, this.pointMul(G, t)); | ||
// const prefix = Buffer.from(q.y % 2n === 0n ? '\x02': '\x03'); | ||
const prefix = Buffer.from([0x02]); | ||
return Buffer.concat([prefix, Taproot.bufferFromInt(q.x)]); | ||
return Buffer.concat([prefix, this.bufferFromInt(q.x)]); | ||
} | ||
@@ -412,42 +317,26 @@ | ||
* | ||
* @param {Buffer} pubkey | ||
* @param {Array} scriptTree | ||
* @returns {Buffer} | ||
*/ | ||
static pubkeyToTaprootTweakPubkey(pubkey) { | ||
let h = ""; | ||
return Taproot.taprootTweakPubkey(pubkey, Buffer.from(h, "ascii")); | ||
} | ||
/** | ||
* | ||
* @param {Buffer} seckey | ||
* @param {Array} scriptTree | ||
* @returns {Buffer} | ||
* @returns {Buffer} tapTweakSeckey | ||
*/ | ||
static seckeyToTaprootTweakSeckey(seckey) { | ||
let h = ""; | ||
return Taproot.taprootTweakSeckey(seckey, Buffer.from(h, "ascii")); | ||
} | ||
let script = ""; | ||
const h = Buffer.from(script, "ascii"); | ||
/** | ||
* | ||
* @param {Buffer} seckey | ||
* @param {Buffer} h | ||
*/ | ||
static taprootTweakSeckey(seckey, h) { | ||
if (!secp256k1.privateKeyVerify(seckey)) { | ||
throw new Error("Invalid seckey."); | ||
} | ||
seckey = Taproot.intFromBuffer(seckey); | ||
const p = Taproot.pointMul(G, seckey); | ||
seckey = Taproot.hasEvenY(p) ? seckey : N - seckey; | ||
const t = Taproot.intFromBuffer( | ||
Taproot.taggedHash( | ||
"TapTweak", | ||
Buffer.concat([Taproot.bufferFromInt(p.x), h]) | ||
) | ||
seckey = this.intFromBuffer(seckey); | ||
const p = this.pointMul(G, seckey); | ||
seckey = this.hasEvenY(p) ? seckey : N - seckey; | ||
const t = this.intFromBuffer( | ||
this.taggedHash("TapTweak", Buffer.concat([this.bufferFromInt(p.x), h])) | ||
); | ||
if (t >= N) throw Error("value error !"); | ||
return Taproot.bufferFromInt((seckey + t) % N); | ||
let tapTweakSeckey = this.bufferFromInt((seckey + t) % N); | ||
if (this.pubkeyGen(tapTweakSeckey)[0] === 3) { | ||
tapTweakSeckey = this.bufferFromInt( | ||
(N - this.intFromBuffer(tapTweakSeckey)) % N | ||
); | ||
} | ||
return tapTweakSeckey; | ||
} | ||
@@ -458,3 +347,3 @@ | ||
* @param {Buffer} data | ||
* @returns {String} | ||
* @returns {string} taproot | ||
*/ | ||
@@ -479,4 +368,4 @@ static bech32mEncode(data) { | ||
* | ||
* @param {String} bech32Address | ||
* @returns {Buffer} | ||
* @param {string} bech32Address | ||
* @returns {Buffer} pubkey | ||
*/ | ||
@@ -501,3 +390,3 @@ static bech32mDecode(bech32Address) { | ||
* @param {Buffer} pubkey | ||
* @returns {Buffer} | ||
* @returns {Buffer} compressed pubkey | ||
*/ | ||
@@ -513,19 +402,9 @@ static compressPubkey(pubkey) { | ||
// /** | ||
// * | ||
// * @param {Buffer} pubkey | ||
// * @returns {String} | ||
// */ | ||
// static pubkeyToLegacyAddress(pubkey) { | ||
// const compressedPubkey = compressPubkey(pubkey); | ||
// return bitcoin.payments.p2pkh({pubkey: compressedPubkey}).address; | ||
// } | ||
/** | ||
* | ||
* @param {Buffer} pubkey | ||
* @returns | ||
* @returns {string} legacy address | ||
*/ | ||
static pubkeyToLegacyAddress(pubkey) { | ||
const compressedPubkey = Taproot.compressPubkey(pubkey); | ||
const compressedPubkey = this.compressPubkey(pubkey); | ||
const sha256Hash = crypto | ||
@@ -555,7 +434,7 @@ .createHash("sha256") | ||
* | ||
* @param {Buffer} taprootTweakPublicKey | ||
* @returns {String} | ||
* @param {Buffer} tapTweakPublicKey | ||
* @returns {string} taproot address | ||
*/ | ||
static taprootTweakPubkeyToTaprootAddress(taprootTweakPublicKey) { | ||
return Taproot.bech32mEncode(taprootTweakPublicKey); | ||
static taprootTweakPubkeyToTaprootAddress(tapTweakPublicKey) { | ||
return this.bech32mEncode(tapTweakPublicKey); | ||
} | ||
@@ -565,10 +444,10 @@ | ||
* | ||
* @param {String} taprootAddress | ||
* @returns {Buffer} | ||
* @param {string} taprootAddress | ||
* @returns {Buffer} odd and even pubkey | ||
*/ | ||
static taprootAddressToTaprootTweakPubkey(taprootAddress) { | ||
// default odd | ||
// default even | ||
return Buffer.concat([ | ||
Buffer.from([0x02]), | ||
Taproot.bech32mDecode(taprootAddress), | ||
this.bech32mDecode(taprootAddress), | ||
]); | ||
@@ -579,9 +458,9 @@ } | ||
* | ||
* @param {String} taprootAddress | ||
* @returns {String} | ||
* @param {string} taprootAddress | ||
* @returns {string} TapTweakLegacyAddress | ||
*/ | ||
static taprootAddressToTaprootTweakLegacyAddress(taprootAddress) { | ||
const taprootTweakPubkey = | ||
Taproot.taprootAddressToTaprootTweakPubkey(taprootAddress); | ||
return Taproot.pubkeyToLegacyAddress(taprootTweakPubkey); | ||
const tapTweakPubkey = | ||
this.taprootAddressToTaprootTweakPubkey(taprootAddress); | ||
return this.pubkeyToLegacyAddress(tapTweakPubkey); | ||
} | ||
@@ -591,13 +470,10 @@ | ||
* wif to taproot | ||
* @param {String} wif | ||
* @returns {String} | ||
* @param {string} wif | ||
* @returns {string} taproot address | ||
*/ | ||
static wifToTaprootAddress(wif) { | ||
const privateKeyHex = Taproot.wifToSeckey(wif); | ||
const publicKey = Taproot.pubkeyGen(privateKeyHex); | ||
const taprootTweakPubkey = Taproot.pubkeyToTaprootTweakPubkey( | ||
publicKey, | ||
null | ||
); | ||
return Taproot.taprootTweakPubkeyToTaprootAddress(taprootTweakPubkey); | ||
const seckey = this.wifToSeckey(wif); | ||
const pubkey = this.pubkeyGen(seckey); | ||
const tapTweakPubkey = this.pubkeyToTaprootTweakPubkey(pubkey); | ||
return this.taprootTweakPubkeyToTaprootAddress(tapTweakPubkey); | ||
} | ||
@@ -604,0 +480,0 @@ } |
{ | ||
"name": "tbc-lib-js", | ||
"version": "1.0.24", | ||
"version": "1.0.25", | ||
"description": "A library for tbc functionality", | ||
@@ -5,0 +5,0 @@ "author": "Austin <austinwang149@gmail.com>", |
@@ -29,3 +29,3 @@ tbc | ||
// get HDPrivateKey from mnemonic | ||
const HDPrivateKey = mnemonic.toHDPrivateKey('','mainnet'); | ||
const HDPrivateKey = mnemonic.toHDPrivateKey('','livenet'); | ||
@@ -32,0 +32,0 @@ // create private key from seed with compressed format |
1112921
24876