diff --git a/package-lock.json b/package-lock.json index f903d235..89f845c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "paillier-bigint": "^3.4.3", "scrypt-ord": "^1.0.16", "scrypt-ts": "^1.3.25", - "scrypt-ts-lib": "^0.1.24" + "scrypt-ts-lib": "^0.1.27" }, "devDependencies": { "@types/chai": "^4.3.4", @@ -834,6 +834,18 @@ } ] }, + "node_modules/bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/bigint-crypto-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz", @@ -859,6 +871,14 @@ "node": ">=8" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -1966,6 +1986,11 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -4265,6 +4290,14 @@ } ] }, + "node_modules/rabinsig": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/rabinsig/-/rabinsig-4.2.1.tgz", + "integrity": "sha512-54BMBXXv5ky0KzKYNo8UMvuqwX6U09Lfvb4uhHdhst6XwTHYc9jOMBK4pBsPtmYM+IOFTSC1/R2akTCg8O8lHw==", + "dependencies": { + "bigint-buffer": "^1.1.5" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -4719,10 +4752,11 @@ } }, "node_modules/scrypt-ts-lib": { - "version": "0.1.24", - "resolved": "https://registry.npmjs.org/scrypt-ts-lib/-/scrypt-ts-lib-0.1.24.tgz", - "integrity": "sha512-AvoY2zyWCcy2vYD36Py01z6Vks9kJKQMfye0fF1sjEaBiGmqywRcrCJWOYqZt+D/+ryBktaCcNjHv8ZRnIM8gg==", + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/scrypt-ts-lib/-/scrypt-ts-lib-0.1.27.tgz", + "integrity": "sha512-Vz9fB7wrjEZnBivArjXAWuJOyUqW2+xFDAXFARUPIFgouzC5kuZkVnO/6ukyy3uwN5cUSZhJO0CRx4HsW0kIrw==", "dependencies": { + "rabinsig": "^4.2.1", "scrypt-ts": "^1.3.2" } }, @@ -6478,6 +6512,14 @@ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, + "bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "requires": { + "bindings": "^1.3.0" + } + }, "bigint-crypto-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz", @@ -6494,6 +6536,14 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -7333,6 +7383,11 @@ "flat-cache": "^3.0.4" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -8923,6 +8978,14 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "rabinsig": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/rabinsig/-/rabinsig-4.2.1.tgz", + "integrity": "sha512-54BMBXXv5ky0KzKYNo8UMvuqwX6U09Lfvb4uhHdhst6XwTHYc9jOMBK4pBsPtmYM+IOFTSC1/R2akTCg8O8lHw==", + "requires": { + "bigint-buffer": "^1.1.5" + } + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -9243,10 +9306,11 @@ } }, "scrypt-ts-lib": { - "version": "0.1.24", - "resolved": "https://registry.npmjs.org/scrypt-ts-lib/-/scrypt-ts-lib-0.1.24.tgz", - "integrity": "sha512-AvoY2zyWCcy2vYD36Py01z6Vks9kJKQMfye0fF1sjEaBiGmqywRcrCJWOYqZt+D/+ryBktaCcNjHv8ZRnIM8gg==", + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/scrypt-ts-lib/-/scrypt-ts-lib-0.1.27.tgz", + "integrity": "sha512-Vz9fB7wrjEZnBivArjXAWuJOyUqW2+xFDAXFARUPIFgouzC5kuZkVnO/6ukyy3uwN5cUSZhJO0CRx4HsW0kIrw==", "requires": { + "rabinsig": "^4.2.1", "scrypt-ts": "^1.3.2" } }, diff --git a/package.json b/package.json index 7b381967..55a8b049 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "paillier-bigint": "^3.4.3", "scrypt-ord": "^1.0.16", "scrypt-ts": "^1.3.25", - "scrypt-ts-lib": "^0.1.24" + "scrypt-ts-lib": "^0.1.27" }, "devDependencies": { "@types/chai": "^4.3.4", diff --git a/src/contracts/blockPRNG.ts b/src/contracts/blockPRNG.ts index b880a056..0f5b1410 100644 --- a/src/contracts/blockPRNG.ts +++ b/src/contracts/blockPRNG.ts @@ -42,7 +42,7 @@ export class BlockchainPRNG extends SmartContract { assert(Blockchain.isValidBlockHeader(bh, this.blockchainTarget)) // verify previous transaction in the block - assert(Blockchain.txInBlock(prevTxid, bh, merkleproof)) + assert(Blockchain.txInBlock(prevTxid, bh, merkleproof, 32)) // use block header's nonce last bit as apseudo-random number const winner: PubKey = bh.nonce % 2n ? this.alice : this.bob diff --git a/src/contracts/bsv20LendingPool.ts b/src/contracts/bsv20LendingPool.ts index 225bcd4f..4d52faf9 100644 --- a/src/contracts/bsv20LendingPool.ts +++ b/src/contracts/bsv20LendingPool.ts @@ -149,7 +149,7 @@ export class Bsv20LendingPool extends BSV20V2 { 'BH does not meet min target' ) assert( - Blockchain.txInBlock(prevTxid, blockHeader, merkleProof), + Blockchain.txInBlock(prevTxid, blockHeader, merkleProof, 32), 'invalid Merkle proof' ) @@ -259,7 +259,7 @@ export class Bsv20LendingPool extends BSV20V2 { 'BH does not meet min target' ) assert( - Blockchain.txInBlock(prevTxid, blockHeader, merkleProof), + Blockchain.txInBlock(prevTxid, blockHeader, merkleProof, 32), 'invalid Merkle proof' ) diff --git a/src/contracts/bsv20LoanMultiple.ts b/src/contracts/bsv20LoanMultiple.ts index 292b14dd..702dc9fb 100644 --- a/src/contracts/bsv20LoanMultiple.ts +++ b/src/contracts/bsv20LoanMultiple.ts @@ -182,7 +182,7 @@ export class Bsv20LoanMultiple extends BSV20V2 { 'BH does not meet min target' ) assert( - Blockchain.txInBlock(prevTxid, blockHeader, merkleProof), + Blockchain.txInBlock(prevTxid, blockHeader, merkleProof, 32), 'invalid Merkle proof' ) diff --git a/src/contracts/bsv20LockBtcToMint.ts b/src/contracts/bsv20LockBtcToMint.ts index add3840c..aea5490b 100644 --- a/src/contracts/bsv20LockBtcToMint.ts +++ b/src/contracts/bsv20LockBtcToMint.ts @@ -102,7 +102,7 @@ export class Bsv20LockBtcToMint extends BSV20V2 { // Calc merkle root. const txID = hash256(btcTx) - const merkleRoot = MerklePath.calcMerkleRoot(txID, merkleProof) + const merkleRoot = MerklePath.calcMerkleRoot(txID, merkleProof, 32) // Check if merkle root is included in the first BH. assert( diff --git a/src/contracts/btcSwap.ts b/src/contracts/btcSwap.ts index c0c3f6c6..35ba2c49 100644 --- a/src/contracts/btcSwap.ts +++ b/src/contracts/btcSwap.ts @@ -165,7 +165,7 @@ export class BTCSwap extends SmartContract { // Calc merkle root. const txID = hash256(btcTx) - const merkleRoot = MerklePath.calcMerkleRoot(txID, merkleProof) + const merkleRoot = MerklePath.calcMerkleRoot(txID, merkleProof, 32) // Check if merkle root is included in the first BH. assert( diff --git a/src/contracts/mast.ts b/src/contracts/mast.ts index cd597122..4b13742e 100644 --- a/src/contracts/mast.ts +++ b/src/contracts/mast.ts @@ -33,7 +33,7 @@ export class MAST extends SmartContract { public main(branchScript: ByteString, merklePath: MerkleProof) { // validate branchScript is from the merkle tree assert( - MerklePath.calcMerkleRoot(sha256(branchScript), merklePath) == + MerklePath.calcMerkleRoot(sha256(branchScript), merklePath, 32) == this.merkleRoot ) diff --git a/src/contracts/priceBet.ts b/src/contracts/priceBet.ts index fb31191c..917b7b93 100644 --- a/src/contracts/priceBet.ts +++ b/src/contracts/priceBet.ts @@ -9,7 +9,7 @@ import { PubKey, slice, } from 'scrypt-ts' -import { RabinSig, RabinPubKey, RabinVerifierWOC } from 'scrypt-ts-lib' +import { RabinSig, RabinPubKey, WitnessOnChainVerifier } from 'scrypt-ts-lib' export type ExchangeRate = { timestamp: bigint @@ -82,7 +82,7 @@ export class PriceBet extends SmartContract { public unlock(msg: ByteString, sig: RabinSig, winnerSig: Sig) { // Verify oracle signature. assert( - RabinVerifierWOC.verifySig(msg, sig, this.oraclePubKey), + WitnessOnChainVerifier.verifySig(msg, sig, this.oraclePubKey), 'Oracle sig verify failed.' ) diff --git a/src/contracts/treeSig.ts b/src/contracts/treeSig.ts index 86c736d6..a361bb70 100644 --- a/src/contracts/treeSig.ts +++ b/src/contracts/treeSig.ts @@ -1,42 +1,62 @@ -import { ByteString, FixedArray, PubKey, Sha256, Sig, SmartContract, assert, method, prop, sha256, toByteString } from "scrypt-ts"; -import { MerklePath, MerkleProof } from 'scrypt-ts-lib'; +import { + ByteString, + FixedArray, + PubKey, + Sha256, + Sig, + SmartContract, + assert, + method, + prop, + sha256, + toByteString, +} from 'scrypt-ts' +import { MerklePath, MerkleProof } from 'scrypt-ts-lib' // tree signatures: Merkle tree-based multisig -export class TreeSig extends SmartContract{ - - +export class TreeSig extends SmartContract { // M out of N multisig - static readonly M : bigint = 3n; - + static readonly M: bigint = 3n + @prop() - readonly merkleRoot : Sha256; + readonly merkleRoot: Sha256 - constructor(merkleRoot : Sha256){ + constructor(merkleRoot: Sha256) { super(...arguments) this.merkleRoot = merkleRoot } @method() - public main(pubKeys : FixedArray, sigs : FixedArray , merkleproof : MerkleProof) { + public main( + pubKeys: FixedArray, + sigs: FixedArray, + merkleproof: MerkleProof + ) { // validate public keys are from the merkle tree - assert(MerklePath.calcMerkleRoot(TreeSig.pubKeys2Leaf(pubKeys), merkleproof) == this.merkleRoot); + assert( + MerklePath.calcMerkleRoot( + TreeSig.pubKeys2Leaf(pubKeys), + merkleproof, + 32 + ) == this.merkleRoot + ) // check if all M signatures are valid - let allMatch :boolean = true; - for (let i = 0; i < 3; i ++) { - allMatch = allMatch && this.checkMultiSig(sigs, pubKeys); + let allMatch: boolean = true + for (let i = 0; i < 3; i++) { + allMatch = allMatch && this.checkMultiSig(sigs, pubKeys) } - assert(allMatch); + assert(allMatch) } // map public keys to a leaf @method() - static pubKeys2Leaf(pubKeys : FixedArray) : Sha256 { - let leaf : ByteString = toByteString(''); + static pubKeys2Leaf(pubKeys: FixedArray): Sha256 { + let leaf: ByteString = toByteString('') - for (let i = 0; i < 3; i ++) { - leaf += pubKeys[i]; + for (let i = 0; i < 3; i++) { + leaf += pubKeys[i] } - return sha256(leaf); + return sha256(leaf) } }