Skip to content
This repository was archived by the owner on Sep 12, 2026. It is now read-only.

Commit df5516b

Browse files
tieroaltafan
andauthored
Bump deps (#137)
* Bump dependencies --------- Co-authored-by: altafan <18440657+altafan@users.noreply.github.com>
1 parent 1062f2b commit df5516b

7 files changed

Lines changed: 668 additions & 309 deletions

File tree

‎package.json‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"@types/node": "^16.11.7",
7171
"@types/proxyquire": "^1.3.28",
7272
"@vulpemventures/secp256k1-zkp": "^3.1.0",
73-
"axios": "^1.8.2",
73+
"axios": "^1.12.0",
7474
"bip32": "^4.0.0",
7575
"bip39": "^3.0.2",
7676
"bip65": "^1.0.1",
@@ -93,5 +93,15 @@
9393
"tslint": "^6.1.3",
9494
"typescript": "^4.4.4"
9595
},
96+
"resolutions": {
97+
"cipher-base": "^1.0.7",
98+
"sha.js": "^2.4.12",
99+
"pbkdf2": "^3.1.6",
100+
"base-x": "^3.0.11",
101+
"@babel/traverse": "^7.23.2",
102+
"cross-spawn": "^7.0.6",
103+
"json5": "^2.2.3",
104+
"picomatch": "^2.3.2"
105+
},
96106
"license": "MIT"
97107
}

‎src/confidential.d.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export declare class Confidential {
3737
blindValueProof(value: string, valueCommitment: Buffer, assetCommitment: Buffer, valueBlinder: Buffer, nonce: Buffer): Buffer;
3838
blindAssetProof(asset: Buffer, assetCommitment: Buffer, assetBlinder: Buffer): Buffer;
3939
assetBlindProofVerify(asset: Buffer, assetCommitment: Buffer, proof: Buffer): boolean;
40+
isUnblindedAssetValid: (output: Output, unblinded: UnblindOutputResult) => boolean;
4041
}
4142
export declare function confidentialValueToSatoshi(value: Buffer): number;
4243
export declare function satoshiToConfidentialValue(amount: number): Buffer;

‎src/confidential.js‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ const value_1 = require('./value');
5454
class Confidential {
5555
constructor(zkp) {
5656
this.zkp = zkp;
57+
this.isUnblindedAssetValid = (output, unblinded) =>
58+
this.assetCommitment(
59+
unblinded.asset,
60+
unblinded.assetBlindingFactor,
61+
).equals(Buffer.from(output.asset));
5762
}
5863
nonceHash(pubkey, privkey) {
5964
return crypto.sha256(Buffer.from(this.zkp.ecdh(pubkey, privkey)));
@@ -103,12 +108,16 @@ class Confidential {
103108
nonce,
104109
out.script,
105110
);
106-
return {
111+
const res = {
107112
value,
108113
asset: Buffer.from(message.slice(0, 32)),
109114
valueBlindingFactor: Buffer.from(blinder),
110115
assetBlindingFactor: Buffer.from(message.slice(32)),
111116
};
117+
if (!this.isUnblindedAssetValid(out, res)) {
118+
throw new Error('Unblinded and output asset mistmatch');
119+
}
120+
return res;
112121
}
113122
rangeProofInfo(proof) {
114123
const { rangeproof } = this.zkp;

‎test/confidential.spec.ts‎

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ describe('confidential', () => {
7171
}
7272
});
7373

74-
it('unblind', () => {
75-
fixtures.valid.unblind.forEach(async (f: any) => {
74+
it('unblind', async () => {
75+
for (const f of fixtures.valid.unblind as any[]) {
7676
const out: TxOutput = {
7777
value: f.valueCommitment,
7878
asset: f.assetGenerator,
@@ -97,7 +97,79 @@ describe('confidential', () => {
9797
unblindProof.assetBlindingFactor.toString('hex'),
9898
f.expected.assetBlindingFactor,
9999
);
100-
});
100+
}
101+
});
102+
103+
it('isUnblindedAssetValid', async () => {
104+
for (const f of fixtures.valid.rangeproof as any[]) {
105+
const zkpLib = await secp256k1();
106+
const confidential = new Confidential(zkpLib);
107+
108+
const asset = Buffer.from(f.asset, 'hex');
109+
const assetCommitment = Buffer.from(f.assetCommitment, 'hex');
110+
const valueCommitment = Buffer.from(f.valueCommitment, 'hex');
111+
const valueBlindingFactor = Buffer.from(f.valueBlindingFactor, 'hex');
112+
const assetBlindingFactor = Buffer.from(f.assetBlindingFactor, 'hex');
113+
const scriptPubkey = Buffer.from(f.scriptPubkey, 'hex');
114+
115+
const nonce = confidential.nonceHash(
116+
Buffer.from(f.blindingPubkey, 'hex'),
117+
Buffer.from(f.ephemeralPrivkey, 'hex'),
118+
);
119+
120+
const buildOutput = (proofAsset: Buffer): TxOutput => ({
121+
value: valueCommitment,
122+
asset: assetCommitment,
123+
script: scriptPubkey,
124+
// a range proof valid for the output's value/asset commitments whose
125+
// embedded message claims `proofAsset`
126+
rangeProof: confidential.rangeProof(
127+
f.value,
128+
proofAsset,
129+
valueCommitment,
130+
assetCommitment,
131+
valueBlindingFactor,
132+
assetBlindingFactor,
133+
nonce,
134+
scriptPubkey,
135+
'1',
136+
'0',
137+
'36',
138+
),
139+
nonce: Buffer.alloc(0),
140+
});
141+
142+
// the asset the output actually commits to is accepted, and unblinding
143+
// succeeds
144+
const validOut = buildOutput(asset);
145+
const unblinded = confidential.unblindOutputWithNonce(validOut, nonce);
146+
assert.strictEqual(
147+
confidential.isUnblindedAssetValid(validOut, unblinded),
148+
true,
149+
);
150+
151+
// an asset id different from the one the output commits to is rejected
152+
const otherAsset = Buffer.from(f.asset, 'hex');
153+
otherAsset[0] ^= 0x01;
154+
const forgedOut = buildOutput(otherAsset);
155+
156+
assert.strictEqual(
157+
confidential.isUnblindedAssetValid(forgedOut, {
158+
value: f.value,
159+
valueBlindingFactor,
160+
asset: otherAsset,
161+
assetBlindingFactor,
162+
}),
163+
false,
164+
);
165+
166+
// unblinding the forged output must throw instead of returning a result
167+
// with a spoofed asset
168+
assert.throws(
169+
() => confidential.unblindOutputWithNonce(forgedOut, nonce),
170+
/Unblinded and output asset/,
171+
);
172+
}
101173
});
102174

103175
it('rangeProofInfo', async () => {

‎test/fixtures/confidential.json‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,20 @@
3939
}
4040
],
4141
"unblind": [
42-
{
43-
"scriptPubkey": "Buffer.from('', 'hex')",
44-
"assetGenerator": "Buffer.from('0ad2641ccd4d87c1207cdf8fe931a0e7959fa92a012320a3df98b3229941bfd534', 'hex')",
45-
"blindingPrivkey": "Buffer.from('9aa45bf2c9a7f3e44192d5d1ff282d60c429bb94836947581dbd66ca0ba00d02', 'hex')",
46-
"ephemeralPubkey": "Buffer.from('031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f', 'hex')",
47-
"valueCommitment": "Buffer.from('096f0d8beac5a1a56f9f3ea6d55c6f4f79e94c4eab9a0f1f28602b6548d3491d43', 'hex')",
48-
"rangeproof": "Buffer.from('4024cfdf01b235e6e17c51d1ba70db19ba96ca9c251fb8a125bca489075a51f4d280a87f9f4735729569609a6d852eec8ef45c9d00822af3cce60290935d0439c97d133b66fa4d3ebc9400aefd9c372688c01ff2386af9205726a13c9701bfaa6603fa2cd79fe49934f63a9fd37c187cdcf0b6ce1894cbc34a819daf7d967cf7aad343c28a3dd0e6582f8911145e850a26bf8d7ea06f5e9446cc5f2b6a9f82f9b3107cdfa2ddf838b890346e996416151d23fac97a641fc173842a266023e3fe44bd7878af21b22b1b7b066d4980ed0611c73c722ba65e142359f5332bb680dccfe24b40d76f5a322738cb730f2a0a4bc705d62abfada8fe4167847dc4bc6efb18ff0c75a82a17672c6eb4b94d71bc63803b6884f6a7d69896cd864e967d1b9ec498edbaffcacebc10f2e974da6c9f39e77ef4d263e4a749c266b504209d39ce784bea6d60049fe745450ce44d84ad60184b5fff0fa11855dd5738ed2ed213afa9101bda59feaa21c05c4cdb4953f0dfba1e2989544d302412c802a660fbe0056bc38ca127d9091898c9c6424ac693da66a9405d7c1a759e19a90fe9c5dd01019303416094fb2c6296db2096ec11df1f169037c08fe48eb2039d20827c9046b02f0d10d3c5baf4672e0747e1a52c555698b7f528489710aa7874a7d1c5cdec6c7f359751b505f597bbf20f0749fdf3dfbff411b91a41a639f09f9a008e09fdf5e87faf3312da31e47c20abc47c757ecae7cf6ef87cfdc48d266c72c581d18c0f33cbbbe2e6d065afe608fd1d2dbe57abfa01726545a3c2b9c85568d5f8f6b743d3e91871859433edf2a5ae5c33f61d05b52ba8d11215f5955e22207f56a80731cfd3d5a86be04e44020043226151e3edeb150522df68a0c6f3d28d5ae12a517095644451dc5cf2773c2e2abb6ca0c39b8b9dc565b07ff35ab49a1170ef87e77606d728abbdbfbd9c699ea5c039ccb8b17c52f14ffb93db491d0fa6704c9155c0f8c4bf3e817686b15b444582beffabd9dba920a8d96c247493c0184e82cca1beef7c8f16141fd26467071b28a881f1d1e4d201b6dfb1173b87f8e6f7de1d5e5533175bac5f9d6d63c00f7adb16268a7c2bc374bc9993d9b5a084a718c8cb91c6403b3494b71822f8dfe2c3af949d5c8c9275a167938adfbe13cd960dce2c6904ff6e07140f27b58e0ed73e3cabdcea8d321e48bd000cf4f568e5da0b89aa139ec66a6ae2c75db15b616e2ee03e941a8d71e5ed7d62bb507af175ec6bde9a1ff8730ecae93f724cd890cfeaffe23fd77faf768033a6b71a35fbf19544a8c762c80d8a44aaad5eaa08bb118d156476478b8615f7c7235d1f375e6bcda1381eed23d28f3ffc33f2fd4121c150e0adbb971f7622014f9ffc8d4ae916d44ad59e6bc9923bba5c6450fb42d5a9a589412c3688bec3b527ac15594f8181cccd5c8466a6e2a0d31de9562f5abfbd34a2fb766961c3e368ee025f7e9f071bd23da46d3b20d39c187df373b647445995c7111c406c3e5a9cd74ebc3eae76cb0539291f3bbd6ec038dc1a693a25aa51d5c458dec91bd90bf53f6ca169edabbcdf8ea73e200794ad9a4a6c265c881c36e6702a20ddb04a68e19d564be553e49aa3f95ee3ab3f05c9f3c02707b666f459e78e57a6d9137739be9f4f2fb85ab40026b5eed57fb2740265878939e1f4206656c9e20403b7e1c6f6bc4256ea2c7fa7c832dbb290bbae1b8084564cac8c34ce980e155f1caac0466a7b59430cc345d7898b91cd53626007ef44bbbd9e1d7a174b5ab818090426c2773928f41bf41aacc8fb45f4c2a8a270f11a409607c4404d67ae1f5b352439ed3bb822687f4eaa6dbf03982c1abbe437bc99ca44b0e5e4a4ca8bea06c79e9c61ade5418dd2cdaf1627912721c5fa5b4f53c1dacdf6d3f7c977a98ea69c399205e51173f13c74cb5993f7186ee6e1c1f7b3bfde06affc80fa271d08d3a239ddd104390e8c68b631a91d2dcf313ff6ab4f68360f323f71606da5c81495be0de9f3031c9f8823332246b66bed20fece4dfd5f6d941188b2eecdaad987a9a268cfb43de818818b4b3b1e3ad58779df32d47ddaa4d2e94ac40f07f413c36d962ebaf82e1abdecb251041d41dd85494cfafcdbf3af426d91740ed6658f70fa65b59ec309529f4b58154f5c6a76e56f6ebe02c3f03d766b460c2919b1ad7ee96a4319198309c3c78e7bfc6c4eaa2a58c8733e81cc3f1d96cb2389ae6d925438169b481c12893eed0822acf379dc053741c8fb9c95e16ec4bd9d350a34284a702c48cac7d62d00616d3e8daa9bed71569d4ad788c72ca7cdbb562d065d8b2dda835dab612407d398467b5b9272b2784ee026e54b3fbccb98fa4ee7b8dea2f673ccf865c4e14a34b6804a26ff6fbad5efd67f711b20c33a754ed143d0f80525ef5b4d74fee1ea093de56daae104596d16a6c23aedf6193ec78b28d7d4eebc3e91bd779d3be58e52d7f785a8264e435edaacb67368e8d4a096643449375426eb7cb81af820d22ecb86ba2c4649bce5427025cbc3f6319829076031c7759ab0825b4960b2849d653757791f43e17e0f97555be5a1846acd681571f859e6d3c6cd411602bc196acb234078391bce1116e66bcfc5bf23f2c7b545122f9112b9aeafc1ea001164b72db16f579550914b1fa0ead1576c1e9e92b923e4d7ff713cb2a62e2b0ed28db2ec9ca22efaf987fd465877e68bf2201e0fff5e116fd225c545500556958f9684a6a2859b867d32386882ab30718af64677f3026e682904c3d794016685d2dedf67381af9dfb385e523115635ffaa1b98d7f2db759c24f3e9979fa52644e8221f88a398ff2a4b8b30027b72bc3ef8b2837a03e688b582b6474f9a283bb40d173d91612c45bbd685b91edb754c2afb6977eeded2196d5faa6f31d1dc332db85462b976a086eee8f93852c7811d51984df3ee43f00466f9974b60d65567ea3437b2ff88d92e9dbba1399edf559fec42057fcf6d1e84538dc892b0c4c3464d1554ccc0d42f7d857ee5ab5510ff439806e4344abe376cc8bd8e0c24a4ca47a5658d2ea4959257bf85055455c51aad47ec65d8b4cd11c3da1f346ae2ae16119c088ed211eb76d01ef527183057f436a42af31f386e9cf31951688e3ebbf590e9377ee33d4f9a630d4c93237e14d543a78db67adddd7e13ca028c94c6c8fb6060b81ad6d47f5ac366d3938f0a41f5e471a7cf7ed4304cf3bea1827285284f5a233e13da4fcc18cc18d04dbfac14be365c1dfba3c88c5232023a4285ed9ce833b1cd56c71bb14882008ecc4828aa558d69ac79827d0cb37b438785f57bc73d8807b572f5cb5a96fb9f76b8d2d8aedce8a056fdc7c779f12ca55b54d1e0984a97dce56ab65dbf1abb8a192d0fba61e72005d4b689f63bc2170ac8642c8eb4bbc38e4baa1ee1f6dac5f9adf3c244acb371768c6faf5143c8330602ea5393bf594241e8f0ae85c8e826fe7061e3c842562b87b4f40f9935b1451c9fc88d4c52cb50491b9a2a156699245c3f3e502334d0b2805648478a615171eb4c26652ed989ecca43637c23cbf2d8e25f8e7feae56db8607084a07b12836fdc55e76bb425b4efec6c5bd1f60a710cb93ef8a94fb36eec384a8c42b00c9852af105273ff35da4e055671bef3960b7a428e999b8bd0f10c6e7d5a4c799e1ec84c509efe3386bda4e67c61eab1ccea3911e3d35bbdc464784b03b69e7514aeccdb42a9a647c847b861cbfec3e062628f9a832d4712b342e9017a0db86e1d47a2c17198cd5929265c7bc36737eb0373e33bee9dc2fcddf9ce275c5900b29e616cc3ca878267f560a5629c76aafa133aa4806d581596f6f6ab89d06c526b3886b91e53f6db61d4947550b62564f31c6aa6b43aca25fa8b568e7cc262e0e351c31f56c55d951b4e74ba09963048673a45ce46b574c964c98acc8ab449b15ee5df95c4d1cb1fc899733955f8c04acd8e4c439ff4b94cab9691bba48657499d4ee3936db4966925621772d47ea75cf6738990eb8013be7e8f0b7e0ed2952e4c3c8cc7c051ad27c5bd4ac5101de9652c2b0ade8fa113f94aba6f0fca4445bf2c6154115524487c5d96189a3e9d8e91fc5042130687bd94b7a0362030a6e2f731497b19ba4b9b25426be79ddd2495975f7a6888a774a319906b81d5ea3cd8868c5800df526f8361abac3e59e0878631b1bb8319de314e382510e21113b12c7a0861', 'hex')",
49-
"expected": {
50-
"value": "99999740000",
51-
"asset": "9520437ce8902eb379a7d8aaa98fc4c94eeb07b6684854868fa6f72bf34b0fd3",
52-
"valueBlindingFactor": "ca4bb9102694dbe0e4b777fd9b199fbdaf51493e2167c24418ec5c3da5024af8",
53-
"assetBlindingFactor": "5dd4b83ac4dc828b033874f818bd0b5575371cc0e1278c554905dfbb49740fda"
42+
{
43+
"scriptPubkey": "Buffer.from('a914d7da691a2b7256aa3bce759ef2b8ff5213fa327987', 'hex')",
44+
"assetGenerator": "Buffer.from('0a8d276fa2ab45fed0f622f818be77f456baa2f3b90456e30d2c561446b25b5458', 'hex')",
45+
"blindingPrivkey": "Buffer.from('1111111111111111111111111111111111111111111111111111111111111111', 'hex')",
46+
"ephemeralPubkey": "Buffer.from('02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27', 'hex')",
47+
"valueCommitment": "Buffer.from('0953c4bf412d07fad5e05fe0f5ea2107a546f9cfef38ef2b962ffd84a89de03d7f', 'hex')",
48+
"rangeproof": "Buffer.from('6023000000000000000168f3002236a83b4085b5f39d5a5756ccd5aedec4920f69f80be894a881a4e32ed8fbd512507e623d7e540d880b1127365a67f760172478312a6a64d0c801535af3d7ca2d5b4733d742f92374368d93196979a59e35d30aabf9f35dba81cfebb99b624311240502eb079118565f23b838dfcfd650095b5e8af0f8c9d2e377b0e7f8a6cc06114775668f818c71815cb0e79380d61d109043844e6f3a7b15d29aaf23f9e66703704022197ffc64f1ab0a716f0a372afce8ce8fbad9bd39bccb8be692fa93134bacb15f153568daeb81fc2da437bb50a4f778591c242bfd59993902bbd189e99245db2342587ea157befdf2137d8560835743e463330d8b1753b0aaad997641ea4682f183a1ff9eb333bb6044ecaf5205702c4de72855baaf507a87a6461009a23d9e24c838e6856c72302289ae4fa80c3f6ae3002aa38787fe32384f8fb9746d5c56b78c4601d4aed27f7397a8a9ba0caacda4c81c6f9a6559e418ff57902742e089d8eabbb76496287ba688e9866e72478d0fa758e3bb7135df9fdbb4494e3c677b8f971b5bf61decb9ac5c19a125026bb01b80237822a338bb38f74f30fcf6cf086ceb279245ff37a68356c72ed7d54d6148e568e5208c8fbeab4a1c4fdcc85f6f8bd6e827750b22f472aa5e9c35db1d2f2a5624b90d30f66ce59c6376a16a63526591e6d515fb1445c5de4c0dbb1f2e74eddeba33e31105f34b6805f848fea2baedc6c3c85363e4b3d28440925f0e0ba4207ca20902ca741682c1d52d80e8251a2c20581bd7edebf5560f84654db221568911dddd191311dd8b6338fc0805049161f177de72da2940bcc960148c00353b6d5d29a576844fabc41450b4f98683bb52689383154cb17dcb28140d203ed7b3d5a4cd421c53fe9260a27a5a9da687a244be0b063b2dad10fa2929c48eed9f0097c83722416b0c7c59efca82fb538d24a5755544247d195263da8889a7d0ceac84448690bb1e79513476e8fa459a1816d10c64b96b191933189264c2b547e5e9f9129cfb59bb9629271ee9e73e75f338fac1b31cd5d2342ed6cf2e6b21081886e90d3eb8a7f9a8c3c7d92023b08ff2815d0c9beaffd71a6a1354b825ca5c16ab4ee0a5804500629b277b8122b8941e85c407517002722d99653967dd592863eccdaa37a44d55b6c98e1bb253a1c40c449aa08c6344dae6e8ce9b953e0ed1cb1d95df644786252ca9d79de83c374ef32a0f8483e9023c8f97603e5bba3ae3bae2a1d79cf0bd73274fd4eb8e6480c75476c424fc21cd2347913d29198d9f9cade0618e58514621678f9d12a7f1edc2c9ed55b3531c3b345f229fd4a5b60d3a2c9c59ffa2d0601ee6f1733e8e562d388cc0cb1afa0bb7925af912cdf925b998416b1f4027ba32a48df4c2ed4d5bd5aad8e424ee0d517d68f875d7d7ba3d56b7aa0d1ffb3bc7be8121303ec681d5a0d8977ec9680489567a87589f18ff74430a1d648141827f4529d1590b580a1668b0076a794e6edeb9abda574c9404777065914dfcdf880891e4ee8c8cda2f590d069001e5ea1f3207bc22a222b6244dae7a708d7d1502aa3831463fe2cef2f17ca1363f37c7abda5df2fc02713ee8d7eb31f2a5cfa69c0fbd0e2cfc522e62529985f0b84cbdf0b67e81d612f43c3a543f04b7f1c9d5727c90288c7c23b48f667bad7820ee08804dcff0162fd8c8931d19b3de6e320b89011ee7048ed611ed888a597729574b6f1fa54270a18c4276f47073ca111cc00fe6e2064ce96e81508ca3be782a1b6dee8f50f132464b435dfdb9ca861c94ba87d15f89e364453166ae527bd90097e8f10514e2219c06de7c11e49d7ec5855c4a62ebb1f62f84091376bc3e55ce9bc17af5b1d8fae6c1da9e3114397a8b59b6eba45b000d16ea03b286b616e480f1fcd472fc2fbc95807e1f06dde230f856ce391af491b1ab93e5f9ebae568d2787c583448fcb8a8cd0dabd62d96d09b8b7385a0bbdd912bd77aa865fc98c928294da2863733d227f23c3aee3783062b7127729deadd1621380dea5029b2557888581a5625da21d430e30885f42c53e11d2cbf41f9eccaaf41c024bbe609db68fd413154043429690237cc75754a523ffde91eaa3e8f206dd75e217fb567db0ce24084c7ec2a5549941f8c31219586d39eb21e4135f2a6cfadd5b3897a09a551e1b389d760a3333f380709edd584c3ab64feadfa61af8ab4f5b8cb1c7671fc0b6ca6db2c6062ed1f118d329c00251fe6d13ddb9a4f960cbf558b1d9366d0a38989eb2561ec5cb494d29817b2a1e57b2c1f62700b655d9e993a7adc803f5d5ffa37a7296afa98da416c9f6c5ba9fa79f0d3c9ac3f937f04e4d06b3ba686c3024928e01b64cc5b4d405faa90b881902f04118e00347e1327ff3277b4772e7cf4800886e1c9732c0a71400fdb6f95fb7b94a5ebb32a73297441d4689fab21b7145dfd54c145c1afb48a843cb8ac0e826091b9cb2527584861dbcfa25b1546094fefc7d0bdc5c21de61b09c3524e60bb29b00bc669decaf573e0cd647087499043e583f146070b3b476f6702fb193d3cf7647c413981a5a0d5e0cca085305c741920dbca05183e424859e2b41e37839b20cdbec8d5a92f4afae818c77778ce827e642ea962c9121c5440a057a09ada06666c9038c0cf9868b2c8ae3a4267d655e9ccaa3d9340337ef20df9861d704b9857fc3ab9a8d5a815abdbc3c663f32c2a4ad88c2d76145794dbf5c3836b75b5c586be6e748c36348434513a32fb3bfb83009d28a85ea40501abc2516db2e1c8e1ad418c4a92a39769474bbedaed63a1fbbca0d3e4ac31c88b0a9403f0d2e709b22e03c35d2c1d91242964aa1aef2b7819c9e18efa1ebff4de3c2bda01e40c7f733e5551587a251335300dfc89d8b3480e75f4b4025c6ab31dfa3f69ab2b2916d1d0f5697f088893202db982df9085b7e8fb27949ca3ee17c0797d320221909eee904abc2b729e807a4909f6c563ead47cd09d0baa14f061ab34b5c0237f792ab7bddb380eb19d9268b8ed49b23649cb4f44a8e3f7d421a835cd7a445a15e84ac8b26b4b43872503418cb8a4126b49a17dacfb261c6825306a791b89b7b9e580633791968bfade5c6d3c64cae89088afe8dc1c2cdc5ab4cc94260a6c208085eb9af40b80b97735c684e9ad70605c855d355cea26388dc5a414d5462865c37ce8a52369408d788729fb3d8451d840ad69c327f51e786e9529527033aea2d34a1e2583cb482a44dd81bab19bf19acd9b78e03f6ed73b66bf4e1102db71e5706899580b5ba18f7501371b0c5bd6ae95e313e3192d0bcc962e5fd662750b837ffd8107c7d793d48005ed354bb0c69ed2b9a03426c45264dfdc878822fdb71fbfba62ec6c3f08cc84f1d34ac51517c660d29f9bce54eef5f6776f86adae318f9f7adf841b8de0e0bb183f44fc75793c3843137910e9183aa433b63dbcaca137f044c062dd51b5c2f1e20fe684913224926171f55b62e824ab7ff48a4ccb4ee43ad62aa93562bc5c58184e25f377355c341821d30cefeb8a69608a8b19047b07c8cfb0f0e01b8f0a5eb929fa3bc751d565dabd986d103c3046e10b1b63fa0c0c46408919ca259f692139d0766cd0f32cfa17da7906738c918ebcc4f6185ccc0c36d257d1ea721f55d8fd4e515179833c5cacec00dd06a3d05e22bc7a875c41ec0917915f448660dac461b13f63136f3074149952a911c328a1d3e2d3f2a019d32991481d0a657d69d7ed7ce7e28f10ac83ffeefc857c9b9397d4f2274ff3b1c67062a3fa3164346ad2cb2a6fdddea6a096aae30aa490c11914b216f0b6dc36d84748c3f3274bc58d94646d7ded7f3f2ef6a18453d8e932a670be728ac0a9c94955d050e4c76003ced73a9d34f272844a79fb31d3fa6e9f4d9a39543cc0c8112039fad9fbb82e412394e8c5bf5db9a3e1aa88488bf46aada32b24c55632b6b5482ad8df6e8b2cf94c4624cfb0cb61cf4f73b527966ded6d49b29080e85a06654e647783510c25fb1b90ebf6d918a07eb38c68b184870063f7b79d8e068aa239a47ce78925ca36d030abfcf2195574a1fdb154f', 'hex')",
49+
"expected": {
50+
"value": "123455000",
51+
"asset": "25b251070e29ca19043cf33ccd7324e2ddab03ecc4ae0b5e77c4fc0e5cf6c95a",
52+
"valueBlindingFactor": "de22de5f5fe49cc6ac2bb8952567151c7c36b42e2e2f2aa587d4ed2060b2ba4d",
53+
"assetBlindingFactor": "c4681a2583b714a31c5a0b997a6c107a96be4aef4847d9cde3035e8ef23642bf"
54+
}
5455
}
55-
}
5656
],
5757
"rangeproofInfo": [
5858
{

‎ts_src/confidential.ts‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,18 @@ export class Confidential {
7777
out.script,
7878
);
7979

80-
return {
80+
const res = {
8181
value,
8282
asset: Buffer.from(message.slice(0, 32)),
8383
valueBlindingFactor: Buffer.from(blinder),
8484
assetBlindingFactor: Buffer.from(message.slice(32)),
8585
};
86+
87+
if (!this.isUnblindedAssetValid(out, res)) {
88+
throw new Error('Unblinded and output asset mistmatch');
89+
}
90+
91+
return res;
8692
}
8793

8894
rangeProofInfo(proof: Buffer): RangeProofInfoResult {
@@ -286,6 +292,14 @@ export class Confidential {
286292
const outGenerator = assetCommitment;
287293
return surjectionproof.verify(proof, inGenerators, outGenerator);
288294
}
295+
296+
isUnblindedAssetValid = (
297+
output: Output,
298+
unblinded: UnblindOutputResult,
299+
): boolean =>
300+
this
301+
.assetCommitment(unblinded.asset, unblinded.assetBlindingFactor)
302+
.equals(Buffer.from(output.asset));
289303
}
290304

291305
export function confidentialValueToSatoshi(value: Buffer): number {
@@ -294,4 +308,4 @@ export function confidentialValueToSatoshi(value: Buffer): number {
294308

295309
export function satoshiToConfidentialValue(amount: number): Buffer {
296310
return ElementsValue.fromNumber(amount).bytes;
297-
}
311+
}

0 commit comments

Comments
 (0)