@@ -3,6 +3,10 @@ import { Secp256k1Curve } from '../../curves';
3
3
import { bigIntFromBufferBE , bigIntToBufferBE } from '../../util' ;
4
4
import { DeserializedDklsSignature } from './types' ;
5
5
import { decode } from 'cbor' ;
6
+ import * as secp256k1 from 'secp256k1' ;
7
+ import { Hash , createHash } from 'crypto' ;
8
+
9
+ const delimeter = ':' ;
6
10
7
11
/**
8
12
* Combines partial signatures from parties participating in DSG.
@@ -27,3 +31,34 @@ export function combinePartialSignatures(round4MessagePayloads: Uint8Array[], rH
27
31
S : new Uint8Array ( bigIntToBufferBE ( normalizedSig . s ) ) ,
28
32
} ;
29
33
}
34
+
35
+ /**
36
+ * Verify a DKLs Signature and serialize it to recid:r:s:publickey format.
37
+ * @param message - message that was signed.
38
+ * @param dklsSignature - R and S values of the ECDSA signature.
39
+ * @param commonKeychain - public key appended to chaincode in hex.
40
+ * @param hash - optional hash function to apply on message before verifying. Default is sha256.
41
+ * @param shouldHash - flag to determine whether message should be hashed before verifying.
42
+ * @returns {string } - serialized signature in `recid:r:s:publickey` format
43
+ */
44
+ export function verifyAndConvertDklsSignature (
45
+ message : Buffer ,
46
+ dklsSignature : DeserializedDklsSignature ,
47
+ commonKeychain : string ,
48
+ hash ?: Hash ,
49
+ shouldHash = true
50
+ ) : string {
51
+ const messageToVerify = shouldHash ? ( hash || createHash ( 'sha256' ) ) . update ( message ) . digest ( ) : message ;
52
+ const pub0 = secp256k1 . ecdsaRecover ( Buffer . concat ( [ dklsSignature . R , dklsSignature . S ] ) , 0 , messageToVerify , true ) ;
53
+ const pub1 = secp256k1 . ecdsaRecover ( Buffer . concat ( [ dklsSignature . R , dklsSignature . S ] ) , 1 , messageToVerify , true ) ;
54
+ const truePub = commonKeychain . slice ( 0 , 66 ) ;
55
+ let recId = 0 ;
56
+ if ( truePub === Buffer . from ( pub1 ) . toString ( 'hex' ) ) {
57
+ recId = 1 ;
58
+ } else if ( truePub !== Buffer . from ( pub0 ) . toString ( 'hex' ) ) {
59
+ throw Error ( 'Invalid Signature' ) ;
60
+ }
61
+ return `${ recId } ${ delimeter } ${ Buffer . from ( dklsSignature . R ) . toString ( 'hex' ) } ${ delimeter } ${ Buffer . from (
62
+ dklsSignature . S
63
+ ) . toString ( 'hex' ) } ${ delimeter } ${ truePub } `;
64
+ }
0 commit comments