import { sm2 } from '@ont-dev/sm.js' ; import * as bip39 from 'bip39' ; import * as elliptic from 'elliptic' ; import * as secureRandom from 'secure-random' ; import * as wif from 'wif' ; import { DEFAULT_ALGORITHM , DEFAULT_SM2_ID , ONT_BIP44_PATH } from '../consts' ; import { ERROR_CODE } from '../error' ; import { decryptWithGcm , encryptWithGcm , ScryptParams } from '../scrypt' ; import { ab2hexstring , hexstring2ab , isBase64 , str2hexstr } from '../utils' ; import { Address } from './address' ; import { Key , KeyParameters } from './Key' ; import { KeyType } from './KeyType' ; import { PublicKey } from './PublicKey' ; import { Signable } from './signable' ; import { Signature } from './Signature' ; import { SignatureScheme } from './SignatureScheme' ; const { HDKey } = require ( '@ont-dev/hdkey-secp256r1' ) ; export class PrivateKey extends Key { param keyType param parameters static random ( keyType ? , parameters ? ) { if ( keyType === undefined ) { keyType = KeyType . fromLabel ( DEFAULT_ALGORITHM . algorithm ) ; } if ( parameters === undefined ) { parameters = KeyParameters . deserializeJson ( DEFAULT_ALGORITHM . parameters ) ; } return new PrivateKey ( ab2hexstring ( secureRandom ( 32 ) ) , keyType , parameters ) ; } param wifkey static deserializeWIF ( wifkey ) { const key = ab2hexstring ( wif . decode ( wifkey , 128 ) . privateKey ) ; return new PrivateKey ( key ) ; } param mnemonic static generateFromMnemonic ( mnemonic , derivePath = ONT_BIP44_PATH ) { if ( mnemonic . split ( ' ' ) . length < 12 ) { throw ERROR_CODE . INVALID_PARAMS ; } const seed = bip39 . mnemonicToSeedHex ( mnemonic ) ; const hdkey = HDKey . fromMasterSeed ( Buffer . from ( seed , 'hex' ) ) ; const pri = hdkey . derive ( derivePath ) ; const key = Buffer . from ( pri . privateKey ) . toString ( 'hex' ) ; const privateKey = new PrivateKey ( key ) ; return privateKey ; } param msg param schema param publicKeyId sign ( msg , schema ? , publicKeyId ? ) { if ( schema === undefined ) { schema = this . algorithm . defaultSchema ; } if ( ! this . isSchemaSupported ( schema ) ) { throw new Error ( 'Signature schema does not match key type.' ) ; } if ( typeof msg !== 'string' ) { msg = msg . getSignContent ( ) ; } let hash ; if ( schema === SignatureScheme . SM2withSM3 ) { hash = msg ; } else { hash = this . computeHash ( msg , schema ) ; } const signed = this . computeSignature ( hash , schema ) ; return new Signature ( schema , signed , publicKeyId ) ; } param msg param schema param publicKeyId async signAsync ( msg , schema ? , publicKeyId ? ) { return this . sign ( msg , schema , publicKeyId ) ; } /**
     * Derives Public key out of Private key.
     */ getPublicKey ( ) { switch ( this . algorithm ) { case KeyType . ECDSA : return this . getEcDSAPublicKey ( ) ; case KeyType . EDDSA : return this . getEdDSAPublicKey ( ) ; case KeyType . SM2 : return this . getSM2PublicKey ( ) ; default : throw new Error ( 'Unsupported signature schema.' ) ; } } param keyphrase param address param param params decrypt ( keyphrase , address , salt , params ? ) { if ( salt . length === 24 && isBase64 ( salt ) ) { salt = Buffer . from ( salt , 'base64' ) . toString ( 'hex' ) ; } const decrypted = decryptWithGcm ( this . key , address , salt , keyphrase , params ) ; const decryptedKey = new PrivateKey ( decrypted , this . algorithm , this . parameters ) ; const pk = decryptedKey . getPublicKey ( ) ; const addrTmp = Address . fromPubKey ( pk ) ; if ( addrTmp . toBase58 ( ) !== address . toBase58 ( ) ) { throw ERROR_CODE . Decrypto_ERROR ; } return decryptedKey ; } param keyphrase param address param salt param params encrypt ( keyphrase , address , salt , params ? ) { const publicKey = this . getPublicKey ( ) ; const addr = Address . fromPubKey ( publicKey ) . toBase58 ( ) ; if ( addr !== address . toBase58 ( ) ) { throw ERROR_CODE . INVALID_ADDR ; } const encrypted = encryptWithGcm ( this . key , address , salt , keyphrase , params ) ; return new PrivateKey ( encrypted , this . algorithm , this . parameters ) ; } /**
     * Derives Public key out of Private key using EcDSA algorithm.
     */ getEcDSAPublicKey ( ) { const ec = new elliptic . ec ( this . parameters . curve . preset ) ; const keyPair = ec . keyFromPrivate ( this . key , 'hex' ) ; const pk = keyPair . getPublic ( true , 'hex' ) ; return new PublicKey ( pk , this . algorithm , this . parameters ) ; } /**
     * Derives Public key out of Private key using EdDSA algorithm.
     */ getEdDSAPublicKey ( ) { const eddsa = new elliptic . eddsa ( this . parameters . curve . preset ) ; const keyPair = eddsa . keyFromSecret ( this . key , 'hex' ) ; const pk = keyPair . getPublic ( true , 'hex' ) ; return new PublicKey ( pk , this . algorithm , this . parameters ) ; } /**
     * Derives Public key out of Private key using SM2 algorithm.
     */ getSM2PublicKey ( ) { const keyPair = sm2 . SM2KeyPair ( null , this . key ) ; const pk = keyPair . pubToString ( 'compress' ) ; return new PublicKey ( pk , this . algorithm , this . parameters ) ; } param hash param schema computeSignature ( hash , schema ) { switch ( schema ) { case SignatureScheme . ECDSAwithSHA224 : case SignatureScheme . ECDSAwithSHA256 : case SignatureScheme . ECDSAwithSHA384 : case SignatureScheme . ECDSAwithSHA512 : case SignatureScheme . ECDSAwithSHA3_224 : case SignatureScheme . ECDSAwithSHA3_256 : case SignatureScheme . ECDSAwithSHA3_384 : case SignatureScheme . ECDSAwithSHA3_512 : case SignatureScheme . ECDSAwithRIPEMD160 : return this . computeEcDSASignature ( hash ) ; case SignatureScheme . EDDSAwithSHA512 : return this . computeEdDSASignature ( hash ) ; case SignatureScheme . SM2withSM3 : return this . computeSM2Signature ( hash ) ; default : throw new Error ( 'Unsupported signature schema.' ) ; } } param hash computeEcDSASignature ( hash ) { const ec = new elliptic . ec ( this . parameters . curve . preset ) ; const signed = ec . sign ( hash , this . key , { canonical : true } ) ; return Buffer . concat ( [ signed . r . toArrayLike ( Buffer , 'be' , 32 ) , signed . s . toArrayLike ( Buffer , 'be' , 32 ) ] ) . toString ( 'hex' ) ; } param hash computeEdDSASignature ( hash ) { const eddsa = new elliptic . eddsa ( this . parameters . curve . preset ) ; const signed = eddsa . sign ( hash , this . key ) ; return signed . toHex ( ) . toLowerCase ( ) ; } param hash computeSM2Signature ( hash ) { const keyPair = sm2 . SM2KeyPair ( null , this . key ) ; const signed = keyPair . sign ( hexstring2ab ( hash ) ) ; const id = DEFAULT_SM2_ID ; return str2hexstr ( id + '\0' ) + signed . r + signed . s ; } /**
     * Gets Wallet Import Format (WIF) representation of the PrivateKey.
     *
     */ serializeWIF ( ) { return wif . encode ( 128 , Buffer . from ( this . key , 'hex' ) , true ) ; } }