-
Notifications
You must be signed in to change notification settings - Fork 286
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(common): Stable Signature Generation from JS Objects
Signed-off-by: suyukuoacn <[email protected]>
- Loading branch information
1 parent
caf60b3
commit 22b5f5c
Showing
8 changed files
with
500 additions
and
6 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 104 additions & 0 deletions
104
packages/cactus-common/src/main/typescript/js-object-signer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { Logger } from "./logging/logger"; | ||
import { LoggerProvider } from "./logging/logger-provider"; | ||
import { LogLevelDesc } from "loglevel"; | ||
|
||
import secp256k1 from "secp256k1"; | ||
import sha3 from "sha3"; | ||
import stringify from "json-stable-stringify"; | ||
|
||
export type SignatureFunction = (msg: any, pkey: any) => any; | ||
export type VerifySignatureFunction = ( | ||
msg: any, | ||
signature: any, | ||
pubKey: Uint8Array | ||
) => boolean; | ||
export type HashFunction = (data: any) => string; | ||
|
||
export interface IJsObjectSignerOptions { | ||
privateKey: any; | ||
signatureFunc?: SignatureFunction; | ||
verifySignatureFunc?: VerifySignatureFunction; | ||
hashFunc?: HashFunction; | ||
logLevel?: LogLevelDesc; | ||
} | ||
|
||
export class JsObjectSigner { | ||
private privateKey: any; | ||
private signatureFunc: any; | ||
private verifySignatureFunc: any; | ||
private hashFunc: any; | ||
private readonly logger: Logger; | ||
|
||
constructor(public readonly options: IJsObjectSignerOptions) { | ||
if (!options) { | ||
throw new Error(`JsObjectSigner#ctor options falsy.`); | ||
} | ||
if (!options.privateKey) { | ||
throw new Error(`JsObjectSigner#ctor options.privateKey falsy.`); | ||
} | ||
|
||
this.privateKey = options.privateKey; | ||
this.signatureFunc = options.signatureFunc; | ||
this.verifySignatureFunc = options.verifySignatureFunc; | ||
this.hashFunc = options.hashFunc; | ||
|
||
this.logger = LoggerProvider.getOrCreate({ | ||
label: "js-object-signer", | ||
level: options.logLevel || "INFO", | ||
}); | ||
} | ||
|
||
/** | ||
* Generate signature from formated message | ||
* @param msg | ||
* @returns Generated signature | ||
*/ | ||
public sign(msg: any): any { | ||
this.logger.debug("Message to sign: " + stringify(msg)); | ||
|
||
if (this.signatureFunc) { | ||
return this.signatureFunc(msg, this.privateKey); | ||
} else { | ||
let hashMsg: any; | ||
if (this.hashFunc) { | ||
hashMsg = this.hashFunc(msg); | ||
} else { | ||
hashMsg = this.dataHash(msg); | ||
} | ||
|
||
const pkey = Buffer.from(this.privateKey, `hex`); | ||
const signObj = secp256k1.ecdsaSign(Buffer.from(hashMsg, `hex`), pkey); | ||
return signObj.signature; | ||
} | ||
} | ||
|
||
/** | ||
* Verify if a signature corresponds to given message and public key | ||
* @param msg | ||
* @param pubKey | ||
* @param signature | ||
* @returns {boolean} | ||
*/ | ||
public verify(msg: any, signature: Uint8Array, pubKey: any): boolean { | ||
if (this.verifySignatureFunc) { | ||
return this.verifySignatureFunc(msg, signature, pubKey); | ||
} | ||
return secp256k1.ecdsaVerify( | ||
signature, | ||
Buffer.from(this.dataHash(msg), `hex`), | ||
pubKey | ||
); | ||
} | ||
|
||
/** | ||
* Format message to be signed | ||
* @param data | ||
* @returns {string} | ||
*/ | ||
private dataHash(data: any): string { | ||
const hashObj = new sha3.SHA3Hash(256); | ||
hashObj.update(stringify(data)); | ||
const hashMsg = hashObj.digest(`hex`); | ||
return hashMsg; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
packages/cactus-common/src/main/typescript/secp256k1-keys.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import crypto from "crypto"; | ||
import secp256k1 from "secp256k1"; | ||
|
||
export interface ISignerKeyPair { | ||
privateKey: any; | ||
publicKey: any; | ||
} | ||
|
||
export class Secp256k1Keys { | ||
/** | ||
* Generate random private and public secp256k1 key in Buffer format | ||
* @return Generated key pair | ||
*/ | ||
static generateKeyPairsBuffer(): ISignerKeyPair { | ||
let privKey: any; | ||
// generate secp256K1 private key | ||
do { | ||
privKey = crypto.randomBytes(32); | ||
} while (!secp256k1.privateKeyVerify(privKey)); | ||
|
||
// generate secp256K1 public key | ||
const pubKey = secp256k1.publicKeyCreate(privKey); | ||
|
||
return { privateKey: privKey, publicKey: pubKey }; | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
packages/cactus-common/src/main/typescript/signer-key-pair.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface ISignerKeyPair { | ||
privateKey: Uint8Array | Buffer | string; | ||
publicKey: Uint8Array | Buffer | string; | ||
} |
Oops, something went wrong.