@@ -6,6 +6,9 @@ let Secp256k1 = require("@dashincubator/secp256k1");
6
6
/**
7
7
* @typedef KeyUtilsPartial
8
8
* @prop {KeySet } set
9
+ * @prop {KeySignAsn1 } signAsn1
10
+ * @prop {KeySignP1363 } signP1363
11
+ * @prop {ASN1ToP1363Signature } asn1ToP1363Signature
9
12
*/
10
13
/** @typedef {TxKeyUtils & KeyUtilsPartial } KeyUtils */
11
14
@@ -15,6 +18,28 @@ let Secp256k1 = require("@dashincubator/secp256k1");
15
18
* @param {KeyInfo } keyInfo
16
19
*/
17
20
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
+
18
43
/** @type {KeyUtils } */
19
44
let KeyUtils = module . exports ;
20
45
@@ -37,6 +62,11 @@ KeyUtils.set = function (id, keyInfo) {
37
62
} ;
38
63
39
64
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 ) {
40
70
let testing = true ;
41
71
let sigOpts = { canonical : true } ;
42
72
if ( ! testing ) {
@@ -45,6 +75,58 @@ KeyUtils.sign = async function (privKeyBytes, hashBytes) {
45
75
let sigBytes = await Secp256k1 . sign ( hashBytes , privKeyBytes , sigOpts ) ;
46
76
return sigBytes ;
47
77
} ;
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
+
48
130
KeyUtils . getPrivateKey = async function ( input ) {
49
131
if ( ! input . address ) {
50
132
//throw new Error('should put the address on the input there buddy...');
0 commit comments