@neuraiproject/neurai-message 0.8.1 → 0.9.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/README.md CHANGED
@@ -1,16 +1,22 @@
1
1
  # neurai-message
2
2
 
3
- Sign and Verify messages in Neurai in JavaScript, primarly for Node.js
3
+ Sign and verify messages in Neurai in JavaScript for Node.js and modern browsers.
4
4
 
5
5
  ## Scope
6
6
 
7
- This package follows the current Neurai `signmessage` / `verifymessage` behavior for `legacy` signatures and also exposes the new `PQ` message-signature format.
7
+ This package follows the current Neurai `signmessage` / `verifymessage` behavior for `legacy` signatures and also exposes the current `PQ` message-signature format bound to `AuthScript` witness-v1 addresses.
8
8
 
9
9
  The package supports two formats:
10
10
 
11
11
  - `legacy`: classic compact `secp256k1` signature encoded in base64 for `P2PKH` / `CKeyID` addresses
12
12
  - `PQ`: Base64 payload `0x35 || CompactSize(pubkey) || pubkey || CompactSize(signature) || signature`
13
13
 
14
+ ## Implementation notes
15
+
16
+ - `legacy` signing and recovery are implemented locally on top of `@noble/secp256k1`
17
+ - `PQ` signing and verification use `@noble/post-quantum/ml-dsa.js`
18
+ - the package no longer depends on `bitcoinjs-message`, `secp256k1`, or `elliptic`
19
+
14
20
  ## Post-Quantum note
15
21
 
16
22
  Neurai `PQ` message signatures do not use compact public-key recovery.
@@ -19,31 +25,36 @@ Instead, the exported signature embeds the serialized public key and the `ML-DSA
19
25
 
20
26
  - decode the Base64 payload
21
27
  - extract the serialized PQ public key
22
- - confirm `HASH160(pubkey_serialized)` matches the witness v1 program in the address
28
+ - derive the default `AuthScript` commitment for `auth_type=0x01` and `witnessScript=OP_TRUE`
29
+ - confirm that 32-byte commitment matches the witness v1 program in the address
23
30
  - verify the `ML-DSA-44` signature over the Neurai message hash
24
31
 
25
32
  The generic `verifyMessage(...)` function now auto-detects both formats. Use `sign(...)` for legacy and `signPQMessage(...)` for PQ.
26
33
 
27
34
  `signPQMessage(...)` expects the ML-DSA-44 secret key and the corresponding public key, either raw (`1312` bytes) or serialized as `0x05 || pubkey`.
28
35
 
29
- ## If you want to use it in the browser, use Browserify
36
+ Legacy PQ witness-v1 keyhash addresses (`OP_1 <20-byte-hash>`) are intentionally not supported anymore. The package now matches the current Neurai `AuthScript` destination model (`OP_1 <32-byte-commitment>`).
30
37
 
31
- @neuraiproject/neurai-message is based on 'bitcoinjs-lib' which uses tons of Node stuff.
38
+ ## Package outputs
32
39
 
33
- To make that work in the browser you need to use Browserify
40
+ This package now publishes explicit entry points:
41
+
42
+ - `@neuraiproject/neurai-message`: main API for Node.js and bundlers
43
+ - `@neuraiproject/neurai-message/browser`: browser ESM build
44
+ - `@neuraiproject/neurai-message/global`: global bundle for `<script src>`
34
45
 
35
46
  ## install
36
47
 
37
- ```
48
+ ```bash
38
49
  npm install @neuraiproject/neurai-message
39
50
 
40
- //If you need to sign messages, install CoinKey
51
+ # If you need to sign legacy messages from WIF, install CoinKey
41
52
  npm install coinkey
42
53
  ```
43
54
 
44
- ## How to use
55
+ ## How to use in Node.js
45
56
 
46
- ```
57
+ ```js
47
58
  const { sign, verifyMessage } = require("@neuraiproject/neurai-message");
48
59
 
49
60
  //coinkey helps us convert from WIF to privatekey
@@ -80,12 +91,25 @@ const CoinKey = require("coinkey");
80
91
  const crypto = require("crypto");
81
92
  const { signPQMessage, verifyPQMessage } = require("@neuraiproject/neurai-message");
82
93
 
94
+ function taggedHash(tag, bytes) {
95
+ const tagHash = crypto.createHash("sha256").update(tag).digest();
96
+ return crypto.createHash("sha256").update(Buffer.concat([tagHash, tagHash, bytes])).digest();
97
+ }
98
+
83
99
  const keys = ml_dsa44.keygen();
84
100
  const serializedPubKey = Buffer.concat([Buffer.from([0x05]), Buffer.from(keys.publicKey)]);
85
- const program = crypto.createHash("ripemd160").update(
86
- crypto.createHash("sha256").update(serializedPubKey).digest()
87
- ).digest();
88
- const words = bech32m.toWords(program);
101
+ const authDescriptor = Buffer.concat([
102
+ Buffer.from([0x01]),
103
+ crypto.createHash("ripemd160").update(
104
+ crypto.createHash("sha256").update(serializedPubKey).digest()
105
+ ).digest(),
106
+ ]);
107
+ const witnessScriptHash = crypto.createHash("sha256").update(Buffer.from([0x51])).digest(); // OP_TRUE
108
+ const commitment = taggedHash(
109
+ "NeuraiAuthScript",
110
+ Buffer.concat([Buffer.from([0x01]), authDescriptor, witnessScriptHash])
111
+ );
112
+ const words = bech32m.toWords(commitment);
89
113
  words.unshift(1);
90
114
  const address = bech32m.encode("tnq", words);
91
115
 
@@ -97,3 +121,27 @@ const CoinKey = require("coinkey");
97
121
  }
98
122
 
99
123
  ```
124
+
125
+ ## How to use in browser ESM
126
+
127
+ ```js
128
+ import { signPQMessage, verifyMessage } from "@neuraiproject/neurai-message/browser";
129
+ ```
130
+
131
+ ## How to use with a global bundle
132
+
133
+ ```html
134
+ <script src="./node_modules/@neuraiproject/neurai-message/dist/NeuraiMessage.global.js"></script>
135
+ <script>
136
+ const ok = NeuraiMessage.verifyMessage(message, address, signature);
137
+ console.log(ok);
138
+ </script>
139
+ ```
140
+
141
+ ## Development
142
+
143
+ ```bash
144
+ npm test
145
+ ```
146
+
147
+ Tests run with `vitest` and cover both `legacy` and `PQ` flows.