Skip to content

Commit 6b46df4

Browse files
committed
fix: use bespoke signatures with 1f byte
1 parent aef25d2 commit 6b46df4

File tree

2 files changed

+94
-4
lines changed

2 files changed

+94
-4
lines changed

demo-static.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ async function main() {
226226

227227
// TODO - AJ is here
228228
console.log(`DEBUG funding outpoint`);
229-
let outpoint = await getFundingOutPointHex(txSigned.transaction, vout);
229+
let outpoint = await getFundingOutPoint(txSigned.transaction, vout);
230230
console.log(outpoint);
231231
let fundingOutPointHex = `${outpoint.txid}${outpoint.voutHex}`;
232232
console.log(fundingOutPointHex);
@@ -397,7 +397,10 @@ async function main() {
397397
console.log(DashTx.utils.bytesToHex(bc));
398398
console.log(bytesToBase64(bc));
399399

400-
let sigBytes = await KeyUtils.sign(assetLockPrivateKey, bc);
400+
let sigBytes = new Uint8Array(65);
401+
sigBytes[0] = 0x1f;
402+
let p1363Bytes = sigBytes.subarray(1);
403+
void (await KeyUtils.signP1363(assetLockPrivateKey, bc, p1363Bytes));
401404
// let sigHex = DashTx.utils.bytesToHex(sigBytes);
402405
Object.assign(stateTransition, {
403406
identity_id: identityId,
@@ -407,7 +410,12 @@ async function main() {
407410
for (let i = 0; i < identityKeys.length; i += 1) {
408411
let key = identityKeys[i];
409412
let stPub = stateTransition.public_keys[i];
410-
let sigBytes = await KeyUtils.sign(key.privateKey, bc);
413+
let sigBytes = new Uint8Array(65);
414+
let p1363Bytes = sigBytes.subarray(1);
415+
// This isn't ASN.1, P1363, or SEC1.
416+
// Not sure what it is (possibly bespoke), but 1f seems to be a magic byte
417+
sigBytes[0] = 0x1f;
418+
void (await KeyUtils.signP1363(key.privateKey, bc, p1363Bytes));
411419
// let sigHex = DashTx.utils.bytesToHex(sigBytes);
412420
Object.assign(stPub, {
413421
// signature: sigHex,
@@ -444,7 +452,7 @@ async function main() {
444452
* @param {Hex} txSignedHex
445453
* @param {Uint32} outputIndex
446454
*/
447-
async function getFundingOutPointHex(txSignedHex, outputIndex) {
455+
async function getFundingOutPoint(txSignedHex, outputIndex) {
448456
let txBytes = DashTx.utils.hexToBytes(txSignedHex);
449457
let txidBytes = await DashTx.doubleSha256(txBytes);
450458
let txidBE = DashTx.utils.bytesToHex(txidBytes);

key-utils.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ let Secp256k1 = require("@dashincubator/secp256k1");
66
/**
77
* @typedef KeyUtilsPartial
88
* @prop {KeySet} set
9+
* @prop {KeySignAsn1} signAsn1
10+
* @prop {KeySignP1363} signP1363
11+
* @prop {ASN1ToP1363Signature} asn1ToP1363Signature
912
*/
1013
/** @typedef {TxKeyUtils & KeyUtilsPartial} KeyUtils */
1114

@@ -15,6 +18,28 @@ let Secp256k1 = require("@dashincubator/secp256k1");
1518
* @param {KeyInfo} keyInfo
1619
*/
1720

21+
/**
22+
* @callback KeySignAsn1
23+
* @param {Uint8Array} privateKey
24+
* @param {Uint8Array} hashBytes
25+
* @returns {Promise<Uint8Array>}
26+
*/
27+
28+
/**
29+
* @callback KeySignP1363
30+
* @param {Uint8Array} privateKey
31+
* @param {Uint8Array} hashBytes
32+
* @param {Uint8Array} [sigBytes] - preallocated 64 bytes
33+
* @returns {Promise<Uint8Array>}
34+
*/
35+
36+
/**
37+
* @callback ASN1ToP1363Signature
38+
* @param {Uint8Array} asn1Sig
39+
* @param {Uint8Array} [sigBytes]
40+
* @returns {Uint8Array} - p1363Sig
41+
*/
42+
1843
/** @type {KeyUtils} */
1944
let KeyUtils = module.exports;
2045

@@ -37,6 +62,11 @@ KeyUtils.set = function (id, keyInfo) {
3762
};
3863

3964
KeyUtils.sign = async function (privKeyBytes, hashBytes) {
65+
let asn1Bytes = await KeyUtils.signAsn1(privKeyBytes, hashBytes);
66+
return asn1Bytes;
67+
};
68+
69+
KeyUtils.signAsn1 = async function (privKeyBytes, hashBytes) {
4070
let testing = true;
4171
let sigOpts = { canonical: true };
4272
if (!testing) {
@@ -45,6 +75,58 @@ KeyUtils.sign = async function (privKeyBytes, hashBytes) {
4575
let sigBytes = await Secp256k1.sign(hashBytes, privKeyBytes, sigOpts);
4676
return sigBytes;
4777
};
78+
79+
KeyUtils.signP1363 = async function (privKeyBytes, hashBytes, sigBytes) {
80+
let asn1Bytes = await KeyUtils.signAsn1(privKeyBytes, hashBytes);
81+
let p1363Bytes = KeyUtils.asn1ToP1363Signature(asn1Bytes, sigBytes);
82+
// TODO DEBUG TESTING
83+
for (let i = 0; i < p1363Bytes.length; i += 1) {
84+
p1363Bytes[i] = 0xff;
85+
}
86+
return p1363Bytes;
87+
};
88+
89+
KeyUtils.asn1ToP1363Signature = function (asn1, p1363Signature) {
90+
if (asn1[0] !== 0x30) {
91+
throw new Error("Invalid DER signature format");
92+
}
93+
94+
let offset = 0;
95+
offset += 2; // skip SEQUENCE and length bytes
96+
97+
offset += 1; // skip type byte
98+
let rLength = asn1[offset];
99+
offset += 1;
100+
let r = asn1.slice(offset, offset + rLength);
101+
102+
offset += rLength;
103+
offset += 1; // skip type byte
104+
let sLength = asn1[offset];
105+
offset += 1;
106+
let s = asn1.slice(offset, offset + sLength);
107+
108+
if (!p1363Signature) {
109+
p1363Signature = new Uint8Array(64);
110+
}
111+
112+
// remove ASN1 padding, or zero-pad the start of r and s, if needed
113+
let rStart = 32 - r.length;
114+
if (rStart === -1) {
115+
r = r.subarray(1);
116+
rStart = 0;
117+
}
118+
p1363Signature.set(r, rStart);
119+
120+
let sStart = 64 - s.length;
121+
if (sStart === 31) {
122+
s = s.subarray(1);
123+
sStart = 32;
124+
}
125+
p1363Signature.set(s, sStart);
126+
127+
return p1363Signature;
128+
};
129+
48130
KeyUtils.getPrivateKey = async function (input) {
49131
if (!input.address) {
50132
//throw new Error('should put the address on the input there buddy...');

0 commit comments

Comments
 (0)