@btc-vision/transaction 1.6.19 → 1.7.1
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/browser/index.js +1 -1
- package/browser/index.js.LICENSE.txt +2 -0
- package/browser/src/_version.d.ts +1 -0
- package/browser/{epoch → src/epoch}/interfaces/IChallengeSolution.d.ts +2 -0
- package/browser/{keypair → src/keypair}/Address.d.ts +7 -4
- package/browser/{keypair → src/keypair}/AddressVerificator.d.ts +3 -0
- package/browser/{keypair → src/keypair}/EcKeyPair.d.ts +3 -2
- package/browser/{keypair → src/keypair}/MessageSigner.d.ts +9 -0
- package/browser/src/keypair/Wallet.d.ts +47 -0
- package/browser/{keypair → src/keypair}/interfaces/IWallet.d.ts +2 -0
- package/browser/src/mnemonic/BIPStandard.d.ts +8 -0
- package/browser/src/mnemonic/Mnemonic.d.ts +34 -0
- package/browser/src/mnemonic/MnemonicStrength.d.ts +7 -0
- package/browser/{opnet.d.ts → src/opnet.d.ts} +5 -0
- package/browser/src/transaction/browser/types/OPWallet.d.ts +14 -0
- package/browser/test/address.test.d.ts +1 -0
- package/browser/test/addressverificator-mldsa.test.d.ts +1 -0
- package/browser/test/derivePath.test.d.ts +1 -0
- package/browser/test/messagesigner-mldsa.test.d.ts +1 -0
- package/browser/test/messagesigner-schnorr.test.d.ts +1 -0
- package/browser/test/network-awareness.test.d.ts +1 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/crypto/crypto-browser.d.ts +11 -0
- package/build/crypto/crypto-browser.js +56 -0
- package/build/epoch/ChallengeSolution.js +3 -2
- package/build/epoch/interfaces/IChallengeSolution.d.ts +2 -0
- package/build/keypair/Address.d.ts +7 -4
- package/build/keypair/Address.js +88 -37
- package/build/keypair/AddressVerificator.d.ts +3 -0
- package/build/keypair/AddressVerificator.js +49 -1
- package/build/keypair/EcKeyPair.d.ts +3 -2
- package/build/keypair/EcKeyPair.js +17 -3
- package/build/keypair/MessageSigner.d.ts +9 -0
- package/build/keypair/MessageSigner.js +23 -0
- package/build/keypair/Wallet.d.ts +20 -3
- package/build/keypair/Wallet.js +108 -9
- package/build/keypair/interfaces/IWallet.d.ts +2 -0
- package/build/mnemonic/BIPStandard.d.ts +8 -0
- package/build/mnemonic/BIPStandard.js +24 -0
- package/build/mnemonic/Mnemonic.d.ts +34 -0
- package/build/mnemonic/Mnemonic.js +140 -0
- package/build/mnemonic/MnemonicStrength.d.ts +7 -0
- package/build/mnemonic/MnemonicStrength.js +8 -0
- package/build/opnet.d.ts +5 -0
- package/build/opnet.js +5 -0
- package/build/transaction/browser/types/OPWallet.d.ts +14 -0
- package/build/transaction/browser/types/OPWallet.js +6 -0
- package/documentation/README.md +32 -0
- package/documentation/quantum-support/01-introduction.md +88 -0
- package/documentation/quantum-support/02-mnemonic-and-wallet.md +445 -0
- package/documentation/quantum-support/03-address-generation.md +329 -0
- package/documentation/quantum-support/04-message-signing.md +623 -0
- package/documentation/quantum-support/05-address-verification.md +307 -0
- package/documentation/quantum-support/README.md +65 -0
- package/gulpfile.js +2 -2
- package/package.json +25 -17
- package/src/_version.ts +1 -1
- package/src/epoch/ChallengeSolution.ts +3 -2
- package/src/epoch/interfaces/IChallengeSolution.ts +2 -0
- package/src/keypair/Address.ts +145 -43
- package/src/keypair/AddressVerificator.ts +87 -2
- package/src/keypair/EcKeyPair.ts +58 -6
- package/src/keypair/MessageSigner.ts +58 -0
- package/src/keypair/Wallet.ts +339 -57
- package/src/keypair/interfaces/IWallet.ts +13 -3
- package/src/mnemonic/BIPStandard.ts +92 -0
- package/src/mnemonic/Mnemonic.ts +465 -0
- package/src/mnemonic/MnemonicStrength.ts +12 -0
- package/src/network/ChainId.ts +1 -4
- package/src/opnet.ts +17 -0
- package/src/transaction/browser/types/OPWallet.ts +73 -0
- package/test/address.test.ts +1068 -0
- package/test/addressverificator-mldsa.test.ts +473 -0
- package/test/derivePath.test.ts +513 -0
- package/test/messagesigner-mldsa.test.ts +1060 -0
- package/test/messagesigner-schnorr.test.ts +1011 -0
- package/test/network-awareness.test.ts +163 -0
- package/tsconfig.json +1 -1
- package/vitest.config.ts +21 -0
- package/browser/_version.d.ts +0 -1
- package/browser/keypair/Wallet.d.ts +0 -30
- package/doc/README.md +0 -0
- /package/browser/{abi → src/abi}/ABICoder.d.ts +0 -0
- /package/browser/{buffer → src/buffer}/BinaryReader.d.ts +0 -0
- /package/browser/{buffer → src/buffer}/BinaryWriter.d.ts +0 -0
- /package/browser/{bytecode → src/bytecode}/Compressor.d.ts +0 -0
- /package/browser/{consensus → src/consensus}/Consensus.d.ts +0 -0
- /package/browser/{consensus → src/consensus}/ConsensusConfig.d.ts +0 -0
- /package/browser/{consensus → src/consensus}/metadata/RoswellConsensus.d.ts +0 -0
- /package/browser/{crypto → src/crypto}/crypto-browser.d.ts +0 -0
- /package/browser/{crypto → src/crypto}/crypto.d.ts +0 -0
- /package/browser/{deterministic → src/deterministic}/AddressMap.d.ts +0 -0
- /package/browser/{deterministic → src/deterministic}/AddressSet.d.ts +0 -0
- /package/browser/{deterministic → src/deterministic}/DeterministicMap.d.ts +0 -0
- /package/browser/{deterministic → src/deterministic}/DeterministicSet.d.ts +0 -0
- /package/browser/{deterministic → src/deterministic}/Map.d.ts +0 -0
- /package/browser/{epoch → src/epoch}/ChallengeSolution.d.ts +0 -0
- /package/browser/{epoch → src/epoch}/validator/EpochValidator.d.ts +0 -0
- /package/browser/{event → src/event}/NetEvent.d.ts +0 -0
- /package/browser/{generators → src/generators}/AddressGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/Features.d.ts +0 -0
- /package/browser/{generators → src/generators}/Generator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/CalldataGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/CustomGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/DeploymentGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/LegacyCalldataGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/MultiSignGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/P2WDAGenerator.d.ts +0 -0
- /package/browser/{index.d.ts → src/index.d.ts} +0 -0
- /package/browser/{keypair → src/keypair}/Secp256k1PointDeriver.d.ts +0 -0
- /package/browser/{metadata → src/metadata}/ContractBaseMetadata.d.ts +0 -0
- /package/browser/{metadata → src/metadata}/tokens.d.ts +0 -0
- /package/browser/{network → src/network}/ChainId.d.ts +0 -0
- /package/browser/{p2wda → src/p2wda}/P2WDADetector.d.ts +0 -0
- /package/browser/{signer → src/signer}/SignerUtils.d.ts +0 -0
- /package/browser/{signer → src/signer}/TweakedSigner.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/ContractAddress.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/TransactionFactory.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/BrowserSignerBase.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/Web3Provider.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/extensions/UnisatSigner.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/extensions/XverseSigner.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/types/Unisat.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/types/Xverse.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/CancelTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/ChallengeSolutionTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/CustomScriptTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/DeploymentTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/FundingTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/InteractionTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/InteractionTransactionP2WDA.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/MultiSignTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/SharedInteractionTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/TransactionBuilder.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/enums/TransactionType.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/interfaces/ITransactionParameters.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/interfaces/Tap.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/mineable/IP2WSHAddress.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/mineable/TimelockGenerator.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/processor/PsbtTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/psbt/PSBTTypes.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/shared/P2TR_MS.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/shared/TweakedTransaction.d.ts +0 -0
- /package/browser/{utils → src/utils}/BitcoinUtils.d.ts +0 -0
- /package/browser/{utils → src/utils}/BufferHelper.d.ts +0 -0
- /package/browser/{utils → src/utils}/StringToBuffer.d.ts +0 -0
- /package/browser/{utils → src/utils}/lengths.d.ts +0 -0
- /package/browser/{utils → src/utils}/types.d.ts +0 -0
- /package/browser/{utxo → src/utxo}/OPNetLimitedProvider.d.ts +0 -0
- /package/browser/{utxo → src/utxo}/interfaces/BroadcastResponse.d.ts +0 -0
- /package/browser/{utxo → src/utxo}/interfaces/IUTXO.d.ts +0 -0
- /package/browser/{verification → src/verification}/TapscriptVerificator.d.ts +0 -0
- /package/{doc → documentation}/addresses/P2OP.md +0 -0
- /package/{doc → documentation}/addresses/P2WDA.md +0 -0
|
@@ -0,0 +1,1060 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { MessageSigner, MLDSASecurityLevel, Mnemonic } from '../build/opnet.js';
|
|
3
|
+
import { networks } from '@btc-vision/bitcoin';
|
|
4
|
+
|
|
5
|
+
describe('MessageSigner ML-DSA', () => {
|
|
6
|
+
const testMnemonic =
|
|
7
|
+
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
|
8
|
+
|
|
9
|
+
describe('signMLDSAMessage', () => {
|
|
10
|
+
it('should sign a message with ML-DSA LEVEL2', () => {
|
|
11
|
+
const mnemonic = new Mnemonic(
|
|
12
|
+
testMnemonic,
|
|
13
|
+
'',
|
|
14
|
+
networks.bitcoin,
|
|
15
|
+
MLDSASecurityLevel.LEVEL2,
|
|
16
|
+
);
|
|
17
|
+
const wallet = mnemonic.derive(0);
|
|
18
|
+
|
|
19
|
+
const message = 'Hello, OPNet!';
|
|
20
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
21
|
+
|
|
22
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
23
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
24
|
+
expect(signed.message).toBeInstanceOf(Uint8Array);
|
|
25
|
+
expect(signed.publicKey).toBeInstanceOf(Uint8Array);
|
|
26
|
+
expect(signed.securityLevel).toBe(MLDSASecurityLevel.LEVEL2);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should sign a message with ML-DSA LEVEL3', () => {
|
|
30
|
+
const mnemonic = new Mnemonic(
|
|
31
|
+
testMnemonic,
|
|
32
|
+
'',
|
|
33
|
+
networks.bitcoin,
|
|
34
|
+
MLDSASecurityLevel.LEVEL3,
|
|
35
|
+
);
|
|
36
|
+
const wallet = mnemonic.derive(0);
|
|
37
|
+
|
|
38
|
+
const message = 'Hello, OPNet!';
|
|
39
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
40
|
+
|
|
41
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
42
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
43
|
+
expect(signed.securityLevel).toBe(MLDSASecurityLevel.LEVEL3);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should sign a message with ML-DSA LEVEL5', () => {
|
|
47
|
+
const mnemonic = new Mnemonic(
|
|
48
|
+
testMnemonic,
|
|
49
|
+
'',
|
|
50
|
+
networks.bitcoin,
|
|
51
|
+
MLDSASecurityLevel.LEVEL5,
|
|
52
|
+
);
|
|
53
|
+
const wallet = mnemonic.derive(0);
|
|
54
|
+
|
|
55
|
+
const message = 'Hello, OPNet!';
|
|
56
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
57
|
+
|
|
58
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
59
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
60
|
+
expect(signed.securityLevel).toBe(MLDSASecurityLevel.LEVEL5);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should sign a Buffer message', () => {
|
|
64
|
+
const mnemonic = new Mnemonic(
|
|
65
|
+
testMnemonic,
|
|
66
|
+
'',
|
|
67
|
+
networks.bitcoin,
|
|
68
|
+
MLDSASecurityLevel.LEVEL2,
|
|
69
|
+
);
|
|
70
|
+
const wallet = mnemonic.derive(0);
|
|
71
|
+
|
|
72
|
+
const message = Buffer.from('Hello, Buffer!', 'utf-8');
|
|
73
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
74
|
+
|
|
75
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
76
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should sign a Uint8Array message', () => {
|
|
80
|
+
const mnemonic = new Mnemonic(
|
|
81
|
+
testMnemonic,
|
|
82
|
+
'',
|
|
83
|
+
networks.bitcoin,
|
|
84
|
+
MLDSASecurityLevel.LEVEL2,
|
|
85
|
+
);
|
|
86
|
+
const wallet = mnemonic.derive(0);
|
|
87
|
+
|
|
88
|
+
const message = new Uint8Array([1, 2, 3, 4, 5]);
|
|
89
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
90
|
+
|
|
91
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
92
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should produce different signatures for different messages', () => {
|
|
96
|
+
const mnemonic = new Mnemonic(
|
|
97
|
+
testMnemonic,
|
|
98
|
+
'',
|
|
99
|
+
networks.bitcoin,
|
|
100
|
+
MLDSASecurityLevel.LEVEL2,
|
|
101
|
+
);
|
|
102
|
+
const wallet = mnemonic.derive(0);
|
|
103
|
+
|
|
104
|
+
const message1 = 'First message';
|
|
105
|
+
const message2 = 'Second message';
|
|
106
|
+
|
|
107
|
+
const signed1 = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message1);
|
|
108
|
+
const signed2 = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message2);
|
|
109
|
+
|
|
110
|
+
expect(Buffer.from(signed1.signature).toString('hex')).not.toBe(
|
|
111
|
+
Buffer.from(signed2.signature).toString('hex'),
|
|
112
|
+
);
|
|
113
|
+
expect(Buffer.from(signed1.message).toString('hex')).not.toBe(
|
|
114
|
+
Buffer.from(signed2.message).toString('hex'),
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should produce different signatures for different wallets with same message', () => {
|
|
119
|
+
const mnemonic = new Mnemonic(
|
|
120
|
+
testMnemonic,
|
|
121
|
+
'',
|
|
122
|
+
networks.bitcoin,
|
|
123
|
+
MLDSASecurityLevel.LEVEL2,
|
|
124
|
+
);
|
|
125
|
+
const wallet1 = mnemonic.derive(0);
|
|
126
|
+
const wallet2 = mnemonic.derive(1);
|
|
127
|
+
|
|
128
|
+
const message = 'Same message';
|
|
129
|
+
|
|
130
|
+
const signed1 = MessageSigner.signMLDSAMessage(wallet1.mldsaKeypair, message);
|
|
131
|
+
const signed2 = MessageSigner.signMLDSAMessage(wallet2.mldsaKeypair, message);
|
|
132
|
+
|
|
133
|
+
expect(Buffer.from(signed1.signature).toString('hex')).not.toBe(
|
|
134
|
+
Buffer.from(signed2.signature).toString('hex'),
|
|
135
|
+
);
|
|
136
|
+
expect(Buffer.from(signed1.publicKey).toString('hex')).not.toBe(
|
|
137
|
+
Buffer.from(signed2.publicKey).toString('hex'),
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should hash the message before signing', () => {
|
|
142
|
+
const mnemonic = new Mnemonic(
|
|
143
|
+
testMnemonic,
|
|
144
|
+
'',
|
|
145
|
+
networks.bitcoin,
|
|
146
|
+
MLDSASecurityLevel.LEVEL2,
|
|
147
|
+
);
|
|
148
|
+
const wallet = mnemonic.derive(0);
|
|
149
|
+
|
|
150
|
+
const message = 'Test message';
|
|
151
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
152
|
+
|
|
153
|
+
// The message in the result should be hashed (32 bytes for SHA-256)
|
|
154
|
+
expect(signed.message.length).toBe(32);
|
|
155
|
+
|
|
156
|
+
// Verify it matches the SHA-256 hash
|
|
157
|
+
const expectedHash = MessageSigner.sha256(Buffer.from(message, 'utf-8'));
|
|
158
|
+
expect(Buffer.from(signed.message).toString('hex')).toBe(expectedHash.toString('hex'));
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
describe('signMLDSAMessage - Buffer input formats', () => {
|
|
163
|
+
it('should sign a Buffer from UTF-8 string', () => {
|
|
164
|
+
const mnemonic = new Mnemonic(
|
|
165
|
+
testMnemonic,
|
|
166
|
+
'',
|
|
167
|
+
networks.bitcoin,
|
|
168
|
+
MLDSASecurityLevel.LEVEL2,
|
|
169
|
+
);
|
|
170
|
+
const wallet = mnemonic.derive(0);
|
|
171
|
+
|
|
172
|
+
const message = Buffer.from('Hello, Buffer!', 'utf-8');
|
|
173
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
174
|
+
|
|
175
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
176
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
177
|
+
expect(signed.message.length).toBe(32);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should sign a Buffer from hex string', () => {
|
|
181
|
+
const mnemonic = new Mnemonic(
|
|
182
|
+
testMnemonic,
|
|
183
|
+
'',
|
|
184
|
+
networks.bitcoin,
|
|
185
|
+
MLDSASecurityLevel.LEVEL2,
|
|
186
|
+
);
|
|
187
|
+
const wallet = mnemonic.derive(0);
|
|
188
|
+
|
|
189
|
+
const message = Buffer.from('deadbeef', 'hex');
|
|
190
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
191
|
+
|
|
192
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
193
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('should sign a Buffer with binary data', () => {
|
|
197
|
+
const mnemonic = new Mnemonic(
|
|
198
|
+
testMnemonic,
|
|
199
|
+
'',
|
|
200
|
+
networks.bitcoin,
|
|
201
|
+
MLDSASecurityLevel.LEVEL2,
|
|
202
|
+
);
|
|
203
|
+
const wallet = mnemonic.derive(0);
|
|
204
|
+
|
|
205
|
+
const message = Buffer.from([0x00, 0x01, 0x02, 0xff, 0xfe, 0xfd]);
|
|
206
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
207
|
+
|
|
208
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
209
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('should sign an empty Buffer', () => {
|
|
213
|
+
const mnemonic = new Mnemonic(
|
|
214
|
+
testMnemonic,
|
|
215
|
+
'',
|
|
216
|
+
networks.bitcoin,
|
|
217
|
+
MLDSASecurityLevel.LEVEL2,
|
|
218
|
+
);
|
|
219
|
+
const wallet = mnemonic.derive(0);
|
|
220
|
+
|
|
221
|
+
const message = Buffer.alloc(0);
|
|
222
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
223
|
+
|
|
224
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
225
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
226
|
+
expect(signed.message.length).toBe(32);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('should sign a Buffer with null bytes', () => {
|
|
230
|
+
const mnemonic = new Mnemonic(
|
|
231
|
+
testMnemonic,
|
|
232
|
+
'',
|
|
233
|
+
networks.bitcoin,
|
|
234
|
+
MLDSASecurityLevel.LEVEL2,
|
|
235
|
+
);
|
|
236
|
+
const wallet = mnemonic.derive(0);
|
|
237
|
+
|
|
238
|
+
const message = Buffer.from([0x00, 0x01, 0x00, 0x02, 0x00]);
|
|
239
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
240
|
+
|
|
241
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
242
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
describe('signMLDSAMessage - Uint8Array input formats', () => {
|
|
247
|
+
it('should sign a basic Uint8Array', () => {
|
|
248
|
+
const mnemonic = new Mnemonic(
|
|
249
|
+
testMnemonic,
|
|
250
|
+
'',
|
|
251
|
+
networks.bitcoin,
|
|
252
|
+
MLDSASecurityLevel.LEVEL2,
|
|
253
|
+
);
|
|
254
|
+
const wallet = mnemonic.derive(0);
|
|
255
|
+
|
|
256
|
+
const message = new Uint8Array([1, 2, 3, 4, 5]);
|
|
257
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
258
|
+
|
|
259
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
260
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
261
|
+
expect(signed.message.length).toBe(32);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('should sign a Uint8Array with all byte values', () => {
|
|
265
|
+
const mnemonic = new Mnemonic(
|
|
266
|
+
testMnemonic,
|
|
267
|
+
'',
|
|
268
|
+
networks.bitcoin,
|
|
269
|
+
MLDSASecurityLevel.LEVEL2,
|
|
270
|
+
);
|
|
271
|
+
const wallet = mnemonic.derive(0);
|
|
272
|
+
|
|
273
|
+
const message = new Uint8Array(256);
|
|
274
|
+
for (let i = 0; i < 256; i++) {
|
|
275
|
+
message[i] = i;
|
|
276
|
+
}
|
|
277
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
278
|
+
|
|
279
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
280
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it('should sign an empty Uint8Array', () => {
|
|
284
|
+
const mnemonic = new Mnemonic(
|
|
285
|
+
testMnemonic,
|
|
286
|
+
'',
|
|
287
|
+
networks.bitcoin,
|
|
288
|
+
MLDSASecurityLevel.LEVEL2,
|
|
289
|
+
);
|
|
290
|
+
const wallet = mnemonic.derive(0);
|
|
291
|
+
|
|
292
|
+
const message = new Uint8Array(0);
|
|
293
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
294
|
+
|
|
295
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
296
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
297
|
+
expect(signed.message.length).toBe(32);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('should sign a Uint8Array from text encoder', () => {
|
|
301
|
+
const mnemonic = new Mnemonic(
|
|
302
|
+
testMnemonic,
|
|
303
|
+
'',
|
|
304
|
+
networks.bitcoin,
|
|
305
|
+
MLDSASecurityLevel.LEVEL2,
|
|
306
|
+
);
|
|
307
|
+
const wallet = mnemonic.derive(0);
|
|
308
|
+
|
|
309
|
+
const encoder = new TextEncoder();
|
|
310
|
+
const message = encoder.encode('Hello, TextEncoder!');
|
|
311
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
312
|
+
|
|
313
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
314
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
describe('signMLDSAMessage - string input formats', () => {
|
|
319
|
+
it('should sign an empty string', () => {
|
|
320
|
+
const mnemonic = new Mnemonic(
|
|
321
|
+
testMnemonic,
|
|
322
|
+
'',
|
|
323
|
+
networks.bitcoin,
|
|
324
|
+
MLDSASecurityLevel.LEVEL2,
|
|
325
|
+
);
|
|
326
|
+
const wallet = mnemonic.derive(0);
|
|
327
|
+
|
|
328
|
+
const message = '';
|
|
329
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
330
|
+
|
|
331
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
332
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
it('should sign a very long string', () => {
|
|
336
|
+
const mnemonic = new Mnemonic(
|
|
337
|
+
testMnemonic,
|
|
338
|
+
'',
|
|
339
|
+
networks.bitcoin,
|
|
340
|
+
MLDSASecurityLevel.LEVEL2,
|
|
341
|
+
);
|
|
342
|
+
const wallet = mnemonic.derive(0);
|
|
343
|
+
|
|
344
|
+
const message = 'A'.repeat(100000);
|
|
345
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
346
|
+
|
|
347
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
348
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
it('should sign a string with special characters', () => {
|
|
352
|
+
const mnemonic = new Mnemonic(
|
|
353
|
+
testMnemonic,
|
|
354
|
+
'',
|
|
355
|
+
networks.bitcoin,
|
|
356
|
+
MLDSASecurityLevel.LEVEL2,
|
|
357
|
+
);
|
|
358
|
+
const wallet = mnemonic.derive(0);
|
|
359
|
+
|
|
360
|
+
const message = '!@#$%^&*()_+-=[]{}|;:",.<>?/~`\n\t\r';
|
|
361
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
362
|
+
|
|
363
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
364
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it('should sign a string with emojis', () => {
|
|
368
|
+
const mnemonic = new Mnemonic(
|
|
369
|
+
testMnemonic,
|
|
370
|
+
'',
|
|
371
|
+
networks.bitcoin,
|
|
372
|
+
MLDSASecurityLevel.LEVEL2,
|
|
373
|
+
);
|
|
374
|
+
const wallet = mnemonic.derive(0);
|
|
375
|
+
|
|
376
|
+
const message = '🚀🌙⭐🪐💫';
|
|
377
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
378
|
+
|
|
379
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
380
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it('should sign a Unicode string with multiple languages', () => {
|
|
384
|
+
const mnemonic = new Mnemonic(
|
|
385
|
+
testMnemonic,
|
|
386
|
+
'',
|
|
387
|
+
networks.bitcoin,
|
|
388
|
+
MLDSASecurityLevel.LEVEL2,
|
|
389
|
+
);
|
|
390
|
+
const wallet = mnemonic.derive(0);
|
|
391
|
+
|
|
392
|
+
const message = '你好世界 🌍 مرحبا العالم Привет мир';
|
|
393
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
394
|
+
|
|
395
|
+
expect(signed.signature).toBeInstanceOf(Uint8Array);
|
|
396
|
+
expect(signed.signature.length).toBeGreaterThan(0);
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
describe('verifyMLDSASignature - string input', () => {
|
|
401
|
+
it('should verify a valid ML-DSA signature with string message', () => {
|
|
402
|
+
const mnemonic = new Mnemonic(
|
|
403
|
+
testMnemonic,
|
|
404
|
+
'',
|
|
405
|
+
networks.bitcoin,
|
|
406
|
+
MLDSASecurityLevel.LEVEL2,
|
|
407
|
+
);
|
|
408
|
+
const wallet = mnemonic.derive(0);
|
|
409
|
+
|
|
410
|
+
const message = 'Hello, OPNet!';
|
|
411
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
412
|
+
|
|
413
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
414
|
+
wallet.mldsaKeypair,
|
|
415
|
+
message,
|
|
416
|
+
signed.signature,
|
|
417
|
+
);
|
|
418
|
+
|
|
419
|
+
expect(isValid).toBe(true);
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it('should verify signature with empty string', () => {
|
|
423
|
+
const mnemonic = new Mnemonic(
|
|
424
|
+
testMnemonic,
|
|
425
|
+
'',
|
|
426
|
+
networks.bitcoin,
|
|
427
|
+
MLDSASecurityLevel.LEVEL2,
|
|
428
|
+
);
|
|
429
|
+
const wallet = mnemonic.derive(0);
|
|
430
|
+
|
|
431
|
+
const message = '';
|
|
432
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
433
|
+
|
|
434
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
435
|
+
wallet.mldsaKeypair,
|
|
436
|
+
message,
|
|
437
|
+
signed.signature,
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
expect(isValid).toBe(true);
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
it('should verify signature with Unicode string', () => {
|
|
444
|
+
const mnemonic = new Mnemonic(
|
|
445
|
+
testMnemonic,
|
|
446
|
+
'',
|
|
447
|
+
networks.bitcoin,
|
|
448
|
+
MLDSASecurityLevel.LEVEL2,
|
|
449
|
+
);
|
|
450
|
+
const wallet = mnemonic.derive(0);
|
|
451
|
+
|
|
452
|
+
const message = '你好世界 🌍';
|
|
453
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
454
|
+
|
|
455
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
456
|
+
wallet.mldsaKeypair,
|
|
457
|
+
message,
|
|
458
|
+
signed.signature,
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
expect(isValid).toBe(true);
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
it('should verify signature with emoji string', () => {
|
|
465
|
+
const mnemonic = new Mnemonic(
|
|
466
|
+
testMnemonic,
|
|
467
|
+
'',
|
|
468
|
+
networks.bitcoin,
|
|
469
|
+
MLDSASecurityLevel.LEVEL2,
|
|
470
|
+
);
|
|
471
|
+
const wallet = mnemonic.derive(0);
|
|
472
|
+
|
|
473
|
+
const message = '🚀🌙⭐';
|
|
474
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
475
|
+
|
|
476
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
477
|
+
wallet.mldsaKeypair,
|
|
478
|
+
message,
|
|
479
|
+
signed.signature,
|
|
480
|
+
);
|
|
481
|
+
|
|
482
|
+
expect(isValid).toBe(true);
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
describe('verifyMLDSASignature - Buffer input', () => {
|
|
487
|
+
it('should verify signature with Buffer message from UTF-8', () => {
|
|
488
|
+
const mnemonic = new Mnemonic(
|
|
489
|
+
testMnemonic,
|
|
490
|
+
'',
|
|
491
|
+
networks.bitcoin,
|
|
492
|
+
MLDSASecurityLevel.LEVEL2,
|
|
493
|
+
);
|
|
494
|
+
const wallet = mnemonic.derive(0);
|
|
495
|
+
|
|
496
|
+
const message = Buffer.from('Hello, Buffer!', 'utf-8');
|
|
497
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
498
|
+
|
|
499
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
500
|
+
wallet.mldsaKeypair,
|
|
501
|
+
message,
|
|
502
|
+
signed.signature,
|
|
503
|
+
);
|
|
504
|
+
|
|
505
|
+
expect(isValid).toBe(true);
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
it('should verify signature with Buffer from hex', () => {
|
|
509
|
+
const mnemonic = new Mnemonic(
|
|
510
|
+
testMnemonic,
|
|
511
|
+
'',
|
|
512
|
+
networks.bitcoin,
|
|
513
|
+
MLDSASecurityLevel.LEVEL2,
|
|
514
|
+
);
|
|
515
|
+
const wallet = mnemonic.derive(0);
|
|
516
|
+
|
|
517
|
+
const message = Buffer.from('deadbeef', 'hex');
|
|
518
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
519
|
+
|
|
520
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
521
|
+
wallet.mldsaKeypair,
|
|
522
|
+
message,
|
|
523
|
+
signed.signature,
|
|
524
|
+
);
|
|
525
|
+
|
|
526
|
+
expect(isValid).toBe(true);
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
it('should verify signature with binary Buffer', () => {
|
|
530
|
+
const mnemonic = new Mnemonic(
|
|
531
|
+
testMnemonic,
|
|
532
|
+
'',
|
|
533
|
+
networks.bitcoin,
|
|
534
|
+
MLDSASecurityLevel.LEVEL2,
|
|
535
|
+
);
|
|
536
|
+
const wallet = mnemonic.derive(0);
|
|
537
|
+
|
|
538
|
+
const message = Buffer.from([0x00, 0x01, 0x02, 0xff]);
|
|
539
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
540
|
+
|
|
541
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
542
|
+
wallet.mldsaKeypair,
|
|
543
|
+
message,
|
|
544
|
+
signed.signature,
|
|
545
|
+
);
|
|
546
|
+
|
|
547
|
+
expect(isValid).toBe(true);
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
it('should verify signature with empty Buffer', () => {
|
|
551
|
+
const mnemonic = new Mnemonic(
|
|
552
|
+
testMnemonic,
|
|
553
|
+
'',
|
|
554
|
+
networks.bitcoin,
|
|
555
|
+
MLDSASecurityLevel.LEVEL2,
|
|
556
|
+
);
|
|
557
|
+
const wallet = mnemonic.derive(0);
|
|
558
|
+
|
|
559
|
+
const message = Buffer.alloc(0);
|
|
560
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
561
|
+
|
|
562
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
563
|
+
wallet.mldsaKeypair,
|
|
564
|
+
message,
|
|
565
|
+
signed.signature,
|
|
566
|
+
);
|
|
567
|
+
|
|
568
|
+
expect(isValid).toBe(true);
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
it('should verify signature with Buffer containing null bytes', () => {
|
|
572
|
+
const mnemonic = new Mnemonic(
|
|
573
|
+
testMnemonic,
|
|
574
|
+
'',
|
|
575
|
+
networks.bitcoin,
|
|
576
|
+
MLDSASecurityLevel.LEVEL2,
|
|
577
|
+
);
|
|
578
|
+
const wallet = mnemonic.derive(0);
|
|
579
|
+
|
|
580
|
+
const message = Buffer.from([0x00, 0x01, 0x00, 0x02, 0x00]);
|
|
581
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
582
|
+
|
|
583
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
584
|
+
wallet.mldsaKeypair,
|
|
585
|
+
message,
|
|
586
|
+
signed.signature,
|
|
587
|
+
);
|
|
588
|
+
|
|
589
|
+
expect(isValid).toBe(true);
|
|
590
|
+
});
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
describe('verifyMLDSASignature - Uint8Array input', () => {
|
|
594
|
+
it('should verify signature with Uint8Array message', () => {
|
|
595
|
+
const mnemonic = new Mnemonic(
|
|
596
|
+
testMnemonic,
|
|
597
|
+
'',
|
|
598
|
+
networks.bitcoin,
|
|
599
|
+
MLDSASecurityLevel.LEVEL2,
|
|
600
|
+
);
|
|
601
|
+
const wallet = mnemonic.derive(0);
|
|
602
|
+
|
|
603
|
+
const message = new Uint8Array([1, 2, 3, 4, 5]);
|
|
604
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
605
|
+
|
|
606
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
607
|
+
wallet.mldsaKeypair,
|
|
608
|
+
message,
|
|
609
|
+
signed.signature,
|
|
610
|
+
);
|
|
611
|
+
|
|
612
|
+
expect(isValid).toBe(true);
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
it('should verify signature with Uint8Array from TextEncoder', () => {
|
|
616
|
+
const mnemonic = new Mnemonic(
|
|
617
|
+
testMnemonic,
|
|
618
|
+
'',
|
|
619
|
+
networks.bitcoin,
|
|
620
|
+
MLDSASecurityLevel.LEVEL2,
|
|
621
|
+
);
|
|
622
|
+
const wallet = mnemonic.derive(0);
|
|
623
|
+
|
|
624
|
+
const encoder = new TextEncoder();
|
|
625
|
+
const message = encoder.encode('Hello, TextEncoder!');
|
|
626
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
627
|
+
|
|
628
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
629
|
+
wallet.mldsaKeypair,
|
|
630
|
+
message,
|
|
631
|
+
signed.signature,
|
|
632
|
+
);
|
|
633
|
+
|
|
634
|
+
expect(isValid).toBe(true);
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
it('should verify signature with empty Uint8Array', () => {
|
|
638
|
+
const mnemonic = new Mnemonic(
|
|
639
|
+
testMnemonic,
|
|
640
|
+
'',
|
|
641
|
+
networks.bitcoin,
|
|
642
|
+
MLDSASecurityLevel.LEVEL2,
|
|
643
|
+
);
|
|
644
|
+
const wallet = mnemonic.derive(0);
|
|
645
|
+
|
|
646
|
+
const message = new Uint8Array(0);
|
|
647
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
648
|
+
|
|
649
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
650
|
+
wallet.mldsaKeypair,
|
|
651
|
+
message,
|
|
652
|
+
signed.signature,
|
|
653
|
+
);
|
|
654
|
+
|
|
655
|
+
expect(isValid).toBe(true);
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
it('should verify signature with Uint8Array containing all byte values', () => {
|
|
659
|
+
const mnemonic = new Mnemonic(
|
|
660
|
+
testMnemonic,
|
|
661
|
+
'',
|
|
662
|
+
networks.bitcoin,
|
|
663
|
+
MLDSASecurityLevel.LEVEL2,
|
|
664
|
+
);
|
|
665
|
+
const wallet = mnemonic.derive(0);
|
|
666
|
+
|
|
667
|
+
const message = new Uint8Array(256);
|
|
668
|
+
for (let i = 0; i < 256; i++) {
|
|
669
|
+
message[i] = i;
|
|
670
|
+
}
|
|
671
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
672
|
+
|
|
673
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
674
|
+
wallet.mldsaKeypair,
|
|
675
|
+
message,
|
|
676
|
+
signed.signature,
|
|
677
|
+
);
|
|
678
|
+
|
|
679
|
+
expect(isValid).toBe(true);
|
|
680
|
+
});
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
describe('verifyMLDSASignature - cross-format verification', () => {
|
|
684
|
+
it('should verify signature signed with string using Buffer', () => {
|
|
685
|
+
const mnemonic = new Mnemonic(
|
|
686
|
+
testMnemonic,
|
|
687
|
+
'',
|
|
688
|
+
networks.bitcoin,
|
|
689
|
+
MLDSASecurityLevel.LEVEL2,
|
|
690
|
+
);
|
|
691
|
+
const wallet = mnemonic.derive(0);
|
|
692
|
+
|
|
693
|
+
const messageString = 'Hello, World!';
|
|
694
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, messageString);
|
|
695
|
+
|
|
696
|
+
const messageBuffer = Buffer.from(messageString, 'utf-8');
|
|
697
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
698
|
+
wallet.mldsaKeypair,
|
|
699
|
+
messageBuffer,
|
|
700
|
+
signed.signature,
|
|
701
|
+
);
|
|
702
|
+
|
|
703
|
+
expect(isValid).toBe(true);
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
it('should verify signature signed with Buffer using string', () => {
|
|
707
|
+
const mnemonic = new Mnemonic(
|
|
708
|
+
testMnemonic,
|
|
709
|
+
'',
|
|
710
|
+
networks.bitcoin,
|
|
711
|
+
MLDSASecurityLevel.LEVEL2,
|
|
712
|
+
);
|
|
713
|
+
const wallet = mnemonic.derive(0);
|
|
714
|
+
|
|
715
|
+
const messageBuffer = Buffer.from('Hello, World!', 'utf-8');
|
|
716
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, messageBuffer);
|
|
717
|
+
|
|
718
|
+
const messageString = 'Hello, World!';
|
|
719
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
720
|
+
wallet.mldsaKeypair,
|
|
721
|
+
messageString,
|
|
722
|
+
signed.signature,
|
|
723
|
+
);
|
|
724
|
+
|
|
725
|
+
expect(isValid).toBe(true);
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
it('should verify signature signed with Uint8Array using Buffer', () => {
|
|
729
|
+
const mnemonic = new Mnemonic(
|
|
730
|
+
testMnemonic,
|
|
731
|
+
'',
|
|
732
|
+
networks.bitcoin,
|
|
733
|
+
MLDSASecurityLevel.LEVEL2,
|
|
734
|
+
);
|
|
735
|
+
const wallet = mnemonic.derive(0);
|
|
736
|
+
|
|
737
|
+
const messageUint8 = new Uint8Array([1, 2, 3, 4, 5]);
|
|
738
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, messageUint8);
|
|
739
|
+
|
|
740
|
+
const messageBuffer = Buffer.from(messageUint8);
|
|
741
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
742
|
+
wallet.mldsaKeypair,
|
|
743
|
+
messageBuffer,
|
|
744
|
+
signed.signature,
|
|
745
|
+
);
|
|
746
|
+
|
|
747
|
+
expect(isValid).toBe(true);
|
|
748
|
+
});
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
describe('verifyMLDSASignature - failure cases', () => {
|
|
752
|
+
it('should fail verification with wrong message', () => {
|
|
753
|
+
const mnemonic = new Mnemonic(
|
|
754
|
+
testMnemonic,
|
|
755
|
+
'',
|
|
756
|
+
networks.bitcoin,
|
|
757
|
+
MLDSASecurityLevel.LEVEL2,
|
|
758
|
+
);
|
|
759
|
+
const wallet = mnemonic.derive(0);
|
|
760
|
+
|
|
761
|
+
const message = 'Hello, OPNet!';
|
|
762
|
+
const wrongMessage = 'Wrong message';
|
|
763
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
764
|
+
|
|
765
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
766
|
+
wallet.mldsaKeypair,
|
|
767
|
+
wrongMessage,
|
|
768
|
+
signed.signature,
|
|
769
|
+
);
|
|
770
|
+
|
|
771
|
+
expect(isValid).toBe(false);
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
it('should fail verification with wrong keypair', () => {
|
|
775
|
+
const mnemonic = new Mnemonic(
|
|
776
|
+
testMnemonic,
|
|
777
|
+
'',
|
|
778
|
+
networks.bitcoin,
|
|
779
|
+
MLDSASecurityLevel.LEVEL2,
|
|
780
|
+
);
|
|
781
|
+
const wallet1 = mnemonic.derive(0);
|
|
782
|
+
const wallet2 = mnemonic.derive(1);
|
|
783
|
+
|
|
784
|
+
const message = 'Hello, OPNet!';
|
|
785
|
+
const signed = MessageSigner.signMLDSAMessage(wallet1.mldsaKeypair, message);
|
|
786
|
+
|
|
787
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
788
|
+
wallet2.mldsaKeypair,
|
|
789
|
+
message,
|
|
790
|
+
signed.signature,
|
|
791
|
+
);
|
|
792
|
+
|
|
793
|
+
expect(isValid).toBe(false);
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
it('should fail verification with corrupted signature', () => {
|
|
797
|
+
const mnemonic = new Mnemonic(
|
|
798
|
+
testMnemonic,
|
|
799
|
+
'',
|
|
800
|
+
networks.bitcoin,
|
|
801
|
+
MLDSASecurityLevel.LEVEL2,
|
|
802
|
+
);
|
|
803
|
+
const wallet = mnemonic.derive(0);
|
|
804
|
+
|
|
805
|
+
const message = 'Hello, OPNet!';
|
|
806
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
807
|
+
|
|
808
|
+
// Corrupt the signature
|
|
809
|
+
const corruptedSignature = Buffer.from(signed.signature);
|
|
810
|
+
corruptedSignature[0] ^= 0xff;
|
|
811
|
+
|
|
812
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
813
|
+
wallet.mldsaKeypair,
|
|
814
|
+
message,
|
|
815
|
+
corruptedSignature,
|
|
816
|
+
);
|
|
817
|
+
|
|
818
|
+
expect(isValid).toBe(false);
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
it('should verify signatures across different security levels', () => {
|
|
822
|
+
const securityLevels = [
|
|
823
|
+
MLDSASecurityLevel.LEVEL2,
|
|
824
|
+
MLDSASecurityLevel.LEVEL3,
|
|
825
|
+
MLDSASecurityLevel.LEVEL5,
|
|
826
|
+
];
|
|
827
|
+
|
|
828
|
+
for (const level of securityLevels) {
|
|
829
|
+
const mnemonic = new Mnemonic(testMnemonic, '', networks.bitcoin, level);
|
|
830
|
+
const wallet = mnemonic.derive(0);
|
|
831
|
+
|
|
832
|
+
const message = `Test message for security level ${level}`;
|
|
833
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
834
|
+
|
|
835
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
836
|
+
wallet.mldsaKeypair,
|
|
837
|
+
message,
|
|
838
|
+
signed.signature,
|
|
839
|
+
);
|
|
840
|
+
|
|
841
|
+
expect(isValid).toBe(true);
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
describe('ML-DSA cross-validation', () => {
|
|
847
|
+
it('should verify signature using public key from signed message', () => {
|
|
848
|
+
const mnemonic = new Mnemonic(
|
|
849
|
+
testMnemonic,
|
|
850
|
+
'',
|
|
851
|
+
networks.bitcoin,
|
|
852
|
+
MLDSASecurityLevel.LEVEL2,
|
|
853
|
+
);
|
|
854
|
+
const wallet = mnemonic.derive(0);
|
|
855
|
+
|
|
856
|
+
const message = 'Cross-validation test';
|
|
857
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
858
|
+
|
|
859
|
+
// Verify that the public key in the signed message matches the wallet's public key
|
|
860
|
+
expect(Buffer.from(signed.publicKey).toString('hex')).toBe(
|
|
861
|
+
Buffer.from(wallet.mldsaKeypair.publicKey).toString('hex'),
|
|
862
|
+
);
|
|
863
|
+
|
|
864
|
+
// Verify the signature
|
|
865
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
866
|
+
wallet.mldsaKeypair,
|
|
867
|
+
message,
|
|
868
|
+
signed.signature,
|
|
869
|
+
);
|
|
870
|
+
|
|
871
|
+
expect(isValid).toBe(true);
|
|
872
|
+
});
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
describe('ML-DSA deterministic signing', () => {
|
|
876
|
+
it('should produce deterministic signatures for the same message and keypair', () => {
|
|
877
|
+
const mnemonic = new Mnemonic(
|
|
878
|
+
testMnemonic,
|
|
879
|
+
'',
|
|
880
|
+
networks.bitcoin,
|
|
881
|
+
MLDSASecurityLevel.LEVEL2,
|
|
882
|
+
);
|
|
883
|
+
const wallet = mnemonic.derive(0);
|
|
884
|
+
|
|
885
|
+
const message = 'Deterministic test';
|
|
886
|
+
const signed1 = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
887
|
+
const signed2 = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
888
|
+
|
|
889
|
+
// ML-DSA signatures might be deterministic or randomized depending on implementation
|
|
890
|
+
// We verify that both signatures are valid regardless
|
|
891
|
+
const isValid1 = MessageSigner.verifyMLDSASignature(
|
|
892
|
+
wallet.mldsaKeypair,
|
|
893
|
+
message,
|
|
894
|
+
signed1.signature,
|
|
895
|
+
);
|
|
896
|
+
const isValid2 = MessageSigner.verifyMLDSASignature(
|
|
897
|
+
wallet.mldsaKeypair,
|
|
898
|
+
message,
|
|
899
|
+
signed2.signature,
|
|
900
|
+
);
|
|
901
|
+
|
|
902
|
+
expect(isValid1).toBe(true);
|
|
903
|
+
expect(isValid2).toBe(true);
|
|
904
|
+
});
|
|
905
|
+
});
|
|
906
|
+
|
|
907
|
+
describe('ML-DSA network awareness', () => {
|
|
908
|
+
it('should produce different signatures for different networks', () => {
|
|
909
|
+
const message = 'Network test';
|
|
910
|
+
|
|
911
|
+
const mnemonicMainnet = new Mnemonic(
|
|
912
|
+
testMnemonic,
|
|
913
|
+
'',
|
|
914
|
+
networks.bitcoin,
|
|
915
|
+
MLDSASecurityLevel.LEVEL2,
|
|
916
|
+
);
|
|
917
|
+
const mnemonicTestnet = new Mnemonic(
|
|
918
|
+
testMnemonic,
|
|
919
|
+
'',
|
|
920
|
+
networks.testnet,
|
|
921
|
+
MLDSASecurityLevel.LEVEL2,
|
|
922
|
+
);
|
|
923
|
+
|
|
924
|
+
const walletMainnet = mnemonicMainnet.derive(0);
|
|
925
|
+
const walletTestnet = mnemonicTestnet.derive(0);
|
|
926
|
+
|
|
927
|
+
const signedMainnet = MessageSigner.signMLDSAMessage(
|
|
928
|
+
walletMainnet.mldsaKeypair,
|
|
929
|
+
message,
|
|
930
|
+
);
|
|
931
|
+
const signedTestnet = MessageSigner.signMLDSAMessage(
|
|
932
|
+
walletTestnet.mldsaKeypair,
|
|
933
|
+
message,
|
|
934
|
+
);
|
|
935
|
+
|
|
936
|
+
// Different networks should produce different signatures
|
|
937
|
+
expect(Buffer.from(signedMainnet.signature).toString('hex')).not.toBe(
|
|
938
|
+
Buffer.from(signedTestnet.signature).toString('hex'),
|
|
939
|
+
);
|
|
940
|
+
|
|
941
|
+
// Verify each signature with its corresponding keypair
|
|
942
|
+
expect(
|
|
943
|
+
MessageSigner.verifyMLDSASignature(
|
|
944
|
+
walletMainnet.mldsaKeypair,
|
|
945
|
+
message,
|
|
946
|
+
signedMainnet.signature,
|
|
947
|
+
),
|
|
948
|
+
).toBe(true);
|
|
949
|
+
expect(
|
|
950
|
+
MessageSigner.verifyMLDSASignature(
|
|
951
|
+
walletTestnet.mldsaKeypair,
|
|
952
|
+
message,
|
|
953
|
+
signedTestnet.signature,
|
|
954
|
+
),
|
|
955
|
+
).toBe(true);
|
|
956
|
+
|
|
957
|
+
// Cross-verification should fail
|
|
958
|
+
expect(
|
|
959
|
+
MessageSigner.verifyMLDSASignature(
|
|
960
|
+
walletMainnet.mldsaKeypair,
|
|
961
|
+
message,
|
|
962
|
+
signedTestnet.signature,
|
|
963
|
+
),
|
|
964
|
+
).toBe(false);
|
|
965
|
+
expect(
|
|
966
|
+
MessageSigner.verifyMLDSASignature(
|
|
967
|
+
walletTestnet.mldsaKeypair,
|
|
968
|
+
message,
|
|
969
|
+
signedMainnet.signature,
|
|
970
|
+
),
|
|
971
|
+
).toBe(false);
|
|
972
|
+
});
|
|
973
|
+
});
|
|
974
|
+
|
|
975
|
+
describe('ML-DSA empty and special messages', () => {
|
|
976
|
+
it('should sign and verify empty string', () => {
|
|
977
|
+
const mnemonic = new Mnemonic(
|
|
978
|
+
testMnemonic,
|
|
979
|
+
'',
|
|
980
|
+
networks.bitcoin,
|
|
981
|
+
MLDSASecurityLevel.LEVEL2,
|
|
982
|
+
);
|
|
983
|
+
const wallet = mnemonic.derive(0);
|
|
984
|
+
|
|
985
|
+
const message = '';
|
|
986
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
987
|
+
|
|
988
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
989
|
+
wallet.mldsaKeypair,
|
|
990
|
+
message,
|
|
991
|
+
signed.signature,
|
|
992
|
+
);
|
|
993
|
+
|
|
994
|
+
expect(isValid).toBe(true);
|
|
995
|
+
});
|
|
996
|
+
|
|
997
|
+
it('should sign and verify very long message', () => {
|
|
998
|
+
const mnemonic = new Mnemonic(
|
|
999
|
+
testMnemonic,
|
|
1000
|
+
'',
|
|
1001
|
+
networks.bitcoin,
|
|
1002
|
+
MLDSASecurityLevel.LEVEL2,
|
|
1003
|
+
);
|
|
1004
|
+
const wallet = mnemonic.derive(0);
|
|
1005
|
+
|
|
1006
|
+
const message = 'A'.repeat(10000);
|
|
1007
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
1008
|
+
|
|
1009
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
1010
|
+
wallet.mldsaKeypair,
|
|
1011
|
+
message,
|
|
1012
|
+
signed.signature,
|
|
1013
|
+
);
|
|
1014
|
+
|
|
1015
|
+
expect(isValid).toBe(true);
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
it('should sign and verify message with special characters', () => {
|
|
1019
|
+
const mnemonic = new Mnemonic(
|
|
1020
|
+
testMnemonic,
|
|
1021
|
+
'',
|
|
1022
|
+
networks.bitcoin,
|
|
1023
|
+
MLDSASecurityLevel.LEVEL2,
|
|
1024
|
+
);
|
|
1025
|
+
const wallet = mnemonic.derive(0);
|
|
1026
|
+
|
|
1027
|
+
const message = '!@#$%^&*()_+-=[]{}|;:",.<>?/~`\n\t\r';
|
|
1028
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
1029
|
+
|
|
1030
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
1031
|
+
wallet.mldsaKeypair,
|
|
1032
|
+
message,
|
|
1033
|
+
signed.signature,
|
|
1034
|
+
);
|
|
1035
|
+
|
|
1036
|
+
expect(isValid).toBe(true);
|
|
1037
|
+
});
|
|
1038
|
+
|
|
1039
|
+
it('should sign and verify Unicode message', () => {
|
|
1040
|
+
const mnemonic = new Mnemonic(
|
|
1041
|
+
testMnemonic,
|
|
1042
|
+
'',
|
|
1043
|
+
networks.bitcoin,
|
|
1044
|
+
MLDSASecurityLevel.LEVEL2,
|
|
1045
|
+
);
|
|
1046
|
+
const wallet = mnemonic.derive(0);
|
|
1047
|
+
|
|
1048
|
+
const message = '你好世界 🌍 مرحبا العالم';
|
|
1049
|
+
const signed = MessageSigner.signMLDSAMessage(wallet.mldsaKeypair, message);
|
|
1050
|
+
|
|
1051
|
+
const isValid = MessageSigner.verifyMLDSASignature(
|
|
1052
|
+
wallet.mldsaKeypair,
|
|
1053
|
+
message,
|
|
1054
|
+
signed.signature,
|
|
1055
|
+
);
|
|
1056
|
+
|
|
1057
|
+
expect(isValid).toBe(true);
|
|
1058
|
+
});
|
|
1059
|
+
});
|
|
1060
|
+
});
|