@smartledger/bsv 4.2.1 → 4.5.0

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.
@@ -59,10 +59,18 @@ function pushTxCore (script) {
59
59
  script.add(gxLe).add(Opcode.OP_ADD) // e + Gx
60
60
  script.add(N_LE).add(Opcode.OP_MOD) // s = (e + Gx) mod n
61
61
  script.add(scriptNum(32)).add(Opcode.OP_NUM2BIN) // s -> 32-byte LE
62
- reverseBytes(script, 32) // -> big-endian (DER INTEGER body)
63
- script.add(DER_PREFIX).add(Opcode.OP_SWAP).add(Opcode.OP_CAT) // PREFIX || s
62
+ reverseBytes(script, 32) // -> big-endian (DER INTEGER body) ; stack: [s_be]
63
+ // Build the DER signature and the pubkey from a SINGLE Gx push (Gx is both the
64
+ // r-value inside the DER prefix and the body of the 02||Gx pubkey). Sharing it
65
+ // via the altstack saves a 32-byte constant vs. embedding Gx twice.
66
+ script.add(Gx).add(Opcode.OP_DUP) // [s_be, Gx, Gx]
67
+ script.add(Buffer.from([0x02])).add(Opcode.OP_SWAP).add(Opcode.OP_CAT) // pubkey = 02||Gx
68
+ script.add(Opcode.OP_TOALTSTACK) // park pubkey ; [s_be, Gx]
69
+ script.add(Buffer.from([0x30, 0x44, 0x02, 0x20])).add(Opcode.OP_SWAP).add(Opcode.OP_CAT) // 30440220||Gx
70
+ script.add(Buffer.from([0x02, 0x20])).add(Opcode.OP_CAT) // ||0220 => DER prefix
71
+ script.add(Opcode.OP_SWAP).add(Opcode.OP_CAT) // DER prefix || s_be
64
72
  script.add(SIGHASH_BYTE).add(Opcode.OP_CAT) // || sighash flag => full DER sig
65
- script.add(PUBKEY).add(Opcode.OP_CHECKSIG) // verify against P = G
73
+ script.add(Opcode.OP_FROMALTSTACK).add(Opcode.OP_CHECKSIG) // pubkey ; verify against P = G
66
74
  return script
67
75
  }
68
76
 
@@ -73,9 +81,8 @@ function authenticator () {
73
81
 
74
82
  /** Extract the committed hashOutputs (item 9, offsetFromEnd 40, len 32) from a preimage on-stack. */
75
83
  function extractHashOutputs (script) {
76
- script.add(Opcode.OP_SIZE).add(scriptNum(40)).add(Opcode.OP_SUB)
77
- .add(Opcode.OP_SPLIT).add(Opcode.OP_NIP)
78
- .add(scriptNum(32)).add(Opcode.OP_SPLIT).add(Opcode.OP_DROP)
84
+ // last 40 bytes, then the first 32 of those = hashOutputs. (BSV string opcodes.)
85
+ script.add(scriptNum(40)).add(Opcode.OP_RIGHT).add(scriptNum(32)).add(Opcode.OP_LEFT)
79
86
  return script
80
87
  }
81
88
 
@@ -98,12 +105,22 @@ function valueCovenant (expectedHashOutputs) {
98
105
  return script
99
106
  }
100
107
 
101
- /** Compute s = (HASH256(preimage)+Gx) mod n; return its 32-byte BE form, or null if not a clean DER template. */
108
+ // floor(n/2) — the canonical low-S boundary (matches Signature.hasLowS()).
109
+ var HALF_N = new BN('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0', 'hex')
110
+
111
+ /**
112
+ * Compute s = (HASH256(preimage)+Gx) mod n; return its 32-byte BE form, or null
113
+ * if the resulting signature would not be a clean, CANONICAL (low-S) DER.
114
+ * Requiring s <= n/2 makes the in-script signature non-malleable and standard,
115
+ * so it passes nodes enforcing SCRIPT_VERIFY_LOW_S — at zero script-size cost
116
+ * (the burden is on the spender's grind, not extra opcodes).
117
+ */
102
118
  function sFromPreimage (preimage) {
103
119
  var z = Hash.sha256sha256(preimage)
104
120
  var s = new BN(z).add(new BN(Gx)).mod(N)
121
+ if (s.gt(HALF_N)) return null // enforce low-S (canonical / non-malleable)
105
122
  var sBE = s.toBuffer('be', 32)
106
- return (sBE[0] >= 0x01 && sBE[0] <= 0x7f) ? sBE : null
123
+ return (sBE[0] >= 0x01) ? sBE : null // s <= n/2 already guarantees sBE[0] <= 0x7f
107
124
  }
108
125
 
109
126
  /**
@@ -41,17 +41,15 @@ function ownershipToken (fee, ownerHash) {
41
41
 
42
42
  // park value (8B @ offsetFromEnd 52) and hashOutputs (32B @ offsetFromEnd 40)
43
43
  s.add(Opcode.OP_DUP)
44
- .add(Opcode.OP_SIZE).add(n(52)).add(Opcode.OP_SUB).add(Opcode.OP_SPLIT).add(Opcode.OP_NIP)
45
- .add(n(8)).add(Opcode.OP_SPLIT).add(Opcode.OP_DROP).add(Opcode.OP_TOALTSTACK) // alt:[value8]
44
+ .add(n(52)).add(Opcode.OP_RIGHT).add(n(8)).add(Opcode.OP_LEFT).add(Opcode.OP_TOALTSTACK) // alt:[value8]
46
45
  s.add(Opcode.OP_DUP); P.extractHashOutputs(s); s.add(Opcode.OP_TOALTSTACK) // alt:[value8, hashOutputs]
47
46
 
48
47
  // scriptChunk = preimage[104 : len-52] (consumes preimage)
49
48
  s.add(n(104)).add(Opcode.OP_SPLIT).add(Opcode.OP_NIP)
50
49
  .add(Opcode.OP_SIZE).add(n(52)).add(Opcode.OP_SUB).add(Opcode.OP_SPLIT).add(Opcode.OP_DROP)
51
50
 
52
- // owner authorization: SHA256(ownerSecret) == ownerHash (chunk[4:36])
53
- s.add(Opcode.OP_DUP).add(n(4)).add(Opcode.OP_SPLIT).add(Opcode.OP_NIP)
54
- .add(n(32)).add(Opcode.OP_SPLIT).add(Opcode.OP_DROP)
51
+ // owner authorization: SHA256(ownerSecret) == ownerHash = chunk[4:36] (OP_SUBSTR)
52
+ s.add(Opcode.OP_DUP).add(n(4)).add(n(32)).add(Opcode.OP_SUBSTR)
55
53
  s.add(n(3)).add(Opcode.OP_ROLL)
56
54
  s.add(Opcode.OP_SHA256).add(Opcode.OP_EQUALVERIFY) // [newOwnerHash, scriptChunk]
57
55
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartledger/bsv",
3
- "version": "4.2.1",
3
+ "version": "4.5.0",
4
4
  "description": "🚀 Complete Bitcoin SV development framework with legally-recognizable DID:web + W3C VC-JWT toolkit, Legal Token Protocol (LTP), Global Digital Attestation Framework (GDAF), StatusList2021 revocation, and 16 flexible loading options. Standards-based credentials with ES256/ES256K support, on-chain BSV anchoring, and comprehensive Bitcoin SV API. Perfect for legal tokens, verifiable credentials, DeFi, smart contracts, and secure Bitcoin applications.",
5
5
  "author": "SmartLedger Technology <hello@smartledger.technology> (https://smartledger.technology)",
6
6
  "homepage": "https://github.com/codenlighten/smartledger-bsv#readme",
@@ -198,6 +198,7 @@
198
198
  "request": "browser-request"
199
199
  },
200
200
  "dependencies": {
201
+ "@smartledger/bsv": "^4.4.0",
201
202
  "aes-js": "^3.1.2",
202
203
  "bn.js": "=4.11.9",
203
204
  "bs58": "=4.0.1",