import { sm2 } from '@ont-dev/sm.js' ; import * as elliptic from 'elliptic' ; import { DEFAULT_SM2_ID } from '../consts' ; import { hexstr2str , hexstring2ab , num2hexstring , StringReader } from '../utils' ; import { CurveLabel } from './CurveLabel' ; import { Key , KeyParameters } from './Key' ; import { KeyType } from './KeyType' ; import { Signable } from './signable' ; import { Signature } from './Signature' ; import { SignatureScheme } from './SignatureScheme' ; /**
 * Class to manage the public key with some userful functions.
 */ export class PublicKey extends Key { param sr param length static deserializeHex ( sr , length = 33 ) { if ( length === 33 ) { const algorithm = KeyType . ECDSA ; const curve = CurveLabel . SECP256R1 ; const pk = sr . read ( 33 ) ; return new PublicKey ( pk , algorithm , new KeyParameters ( curve ) ) ; } else { const algorithmHex = parseInt ( sr . read ( 1 ) , 16 ) ; const curveHex = parseInt ( sr . read ( 1 ) , 16 ) ; const pk = sr . read ( length - 2 ) ; return new PublicKey ( pk , KeyType . fromHex ( algorithmHex ) , new KeyParameters ( CurveLabel . fromHex ( curveHex ) ) ) ; } } param msg param signature verify ( msg , signature ) { if ( ! this . isSchemaSupported ( signature . algorithm ) ) { throw new Error ( 'Signature schema does not match key type.' ) ; } if ( typeof msg !== 'string' ) { msg = msg . getSignContent ( ) ; } let hash ; if ( signature . algorithm === SignatureScheme . SM2withSM3 ) { hash = msg ; } else { hash = this . computeHash ( msg , signature . algorithm ) ; } return this . verifySignature ( hash , signature . value , signature . algorithm ) ; } /**
     * Serializes public key to Hex representation.
     *
     * Length definition is not included.
     */ serializeHex ( ) { let result = '' ; switch ( this . algorithm ) { case KeyType . ECDSA : result += this . key ; break ; case KeyType . EDDSA : case KeyType . SM2 : result += num2hexstring ( this . algorithm . hex ) ; result += num2hexstring ( this . parameters . curve . hex ) ; result += Buffer . from ( this . key , 'hex' ) . toString ( 'hex' ) ; break ; } return result ; } param hash param signature param schema verifySignature ( hash , signature , 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 . verifyEcDSASignature ( hash , signature ) ; case SignatureScheme . EDDSAwithSHA512 : return this . verifyEdDSASignature ( hash , signature ) ; case SignatureScheme . SM2withSM3 : return this . verifySM2Signature ( hash , signature ) ; default : throw new Error ( 'Unsupported signature schema.' ) ; } } param hash param signature verifyEcDSASignature ( hash , signature ) { const r = signature . substr ( 0 , 64 ) ; const s = signature . substr ( 64 , 64 ) ; const ec = new elliptic . ec ( this . parameters . curve . preset ) ; return ec . verify ( hash , { r , s } , this . key , 'hex' ) ; } param hash param signature verifyEdDSASignature ( hash , signature ) { const r = signature . substr ( 0 , 64 ) ; const s = signature . substr ( 64 , 64 ) ; const eddsa = new elliptic . eddsa ( this . parameters . curve . preset ) ; return eddsa . verify ( hash , { r , s } , this . key , 'hex' ) ; } param hash param signature verifySM2Signature ( hash , signature ) { const reader = new StringReader ( signature ) ; const id = hexstr2str ( reader . readNullTerminated ( ) ) ; if ( id !== DEFAULT_SM2_ID && id !== '' ) { throw new Error ( 'Unsupported SM2 id used.' ) ; } const r = reader . read ( 32 ) ; const s = reader . read ( 32 ) ; const keyPair = sm2 . SM2KeyPair ( this . key ) ; return keyPair . verify ( hexstring2ab ( hash ) , r , s ) ; } } /**
 * Public key status enumaration.
 */ export class PublicKeyStatus { static values : PublicKeyStatus [ ] = [ ] ; static IN_USE = new PublicKeyStatus ( 'in use' ) ; static REVOKED = new PublicKeyStatus ( 'revoked' ) ; param label static fromHexLabel ( hexLabel ) { const label = hexstr2str ( hexLabel ) ; const item = PublicKeyStatus . values . find ( ( v ) => v . label === label ) ; if ( item === undefined ) { throw new Error ( 'Enum value not found' ) ; } return item ; } label : string ; constructor ( label ) { this . label = label ; PublicKeyStatus . values . push ( this ) ; } }