PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/avalanche/src/common
Просмотр файла: secp256k1.ts
/**
* @packageDocumentation
* @module Common-SECP256k1KeyChain
*/
import { Buffer } from "buffer/"
import * as elliptic from "elliptic"
import createHash from "create-hash"
import BinTools from "../utils/bintools"
import { StandardKeyPair, StandardKeyChain } from "./keychain"
import { PublicKeyError } from "../utils/errors"
import { BNInput } from "elliptic"
import { Serialization, SerializedType } from "../utils"
/**
* @ignore
*/
const EC: typeof elliptic.ec = elliptic.ec
/**
* @ignore
*/
const ec: elliptic.ec = new EC("secp256k1")
/**
* @ignore
*/
const ecparams: any = ec.curve
/**
* @ignore
*/
const BN: any = ecparams.n.constructor
/**
* @ignore
*/
const bintools: BinTools = BinTools.getInstance()
const serialization: Serialization = Serialization.getInstance()
/**
* Class for representing a private and public keypair on the Platform Chain.
*/
export abstract class SECP256k1KeyPair extends StandardKeyPair {
protected keypair: elliptic.ec.KeyPair
protected chainID: string = ""
protected hrp: string = ""
/**
* @ignore
*/
protected _sigFromSigBuffer(sig: Buffer): elliptic.ec.SignatureOptions {
const r: BNInput = new BN(bintools.copyFrom(sig, 0, 32))
const s: BNInput = new BN(bintools.copyFrom(sig, 32, 64))
const recoveryParam: number = bintools
.copyFrom(sig, 64, 65)
.readUIntBE(0, 1)
const sigOpt = {
r: r,
s: s,
recoveryParam: recoveryParam
}
return sigOpt
}
/**
* Generates a new keypair.
*/
generateKey() {
this.keypair = ec.genKeyPair()
// doing hex translation to get Buffer class
this.privk = Buffer.from(
this.keypair.getPrivate("hex").padStart(64, "0"),
"hex"
)
this.pubk = Buffer.from(
this.keypair.getPublic(true, "hex").padStart(66, "0"),
"hex"
)
}
/**
* Imports a private key and generates the appropriate public key.
*
* @param privk A {@link https://github.com/feross/buffer|Buffer} representing the private key
*
* @returns true on success, false on failure
*/
importKey(privk: Buffer): boolean {
this.keypair = ec.keyFromPrivate(privk.toString("hex"), "hex")
// doing hex translation to get Buffer class
try {
this.privk = Buffer.from(
this.keypair.getPrivate("hex").padStart(64, "0"),
"hex"
)
this.pubk = Buffer.from(
this.keypair.getPublic(true, "hex").padStart(66, "0"),
"hex"
)
return true // silly I know, but the interface requires so it returns true on success, so if Buffer fails validation...
} catch (error) {
return false
}
}
/**
* Returns the address as a {@link https://github.com/feross/buffer|Buffer}.
*
* @returns A {@link https://github.com/feross/buffer|Buffer} representation of the address
*/
getAddress(): Buffer {
return SECP256k1KeyPair.addressFromPublicKey(this.pubk)
}
/**
* Returns the address's string representation.
*
* @returns A string representation of the address
*/
getAddressString(): string {
const addr: Buffer = SECP256k1KeyPair.addressFromPublicKey(this.pubk)
const type: SerializedType = "bech32"
return serialization.bufferToType(addr, type, this.hrp, this.chainID)
}
/**
* Returns an address given a public key.
*
* @param pubk A {@link https://github.com/feross/buffer|Buffer} representing the public key
*
* @returns A {@link https://github.com/feross/buffer|Buffer} for the address of the public key.
*/
static addressFromPublicKey(pubk: Buffer): Buffer {
if (pubk.length === 65) {
/* istanbul ignore next */
pubk = Buffer.from(
ec.keyFromPublic(pubk).getPublic(true, "hex").padStart(66, "0"),
"hex"
) // make compact, stick back into buffer
}
if (pubk.length === 33) {
const sha256: Buffer = Buffer.from(
createHash("sha256").update(pubk).digest()
)
const ripesha: Buffer = Buffer.from(
createHash("ripemd160").update(sha256).digest()
)
return ripesha
}
/* istanbul ignore next */
throw new PublicKeyError("Unable to make address.")
}
/**
* Returns a string representation of the private key.
*
* @returns A cb58 serialized string representation of the private key
*/
getPrivateKeyString(): string {
return `PrivateKey-${bintools.cb58Encode(this.privk)}`
}
/**
* Returns the public key.
*
* @returns A cb58 serialized string representation of the public key
*/
getPublicKeyString(): string {
return bintools.cb58Encode(this.pubk)
}
/**
* Takes a message, signs it, and returns the signature.
*
* @param msg The message to sign, be sure to hash first if expected
*
* @returns A {@link https://github.com/feross/buffer|Buffer} containing the signature
*/
sign(msg: Buffer): Buffer {
const sigObj: elliptic.ec.Signature = this.keypair.sign(msg, undefined, {
canonical: true
})
const recovery: Buffer = Buffer.alloc(1)
recovery.writeUInt8(sigObj.recoveryParam, 0)
const r: Buffer = Buffer.from(sigObj.r.toArray("be", 32)) //we have to skip native Buffer class, so this is the way
const s: Buffer = Buffer.from(sigObj.s.toArray("be", 32)) //we have to skip native Buffer class, so this is the way
const result: Buffer = Buffer.concat([r, s, recovery], 65)
return result
}
/**
* Verifies that the private key associated with the provided public key produces the signature associated with the given message.
*
* @param msg The message associated with the signature
* @param sig The signature of the signed message
*
* @returns True on success, false on failure
*/
verify(msg: Buffer, sig: Buffer): boolean {
const sigObj: elliptic.ec.SignatureOptions = this._sigFromSigBuffer(sig)
return ec.verify(msg, sigObj, this.keypair)
}
/**
* Recovers the public key of a message signer from a message and its associated signature.
*
* @param msg The message that's signed
* @param sig The signature that's signed on the message
*
* @returns A {@link https://github.com/feross/buffer|Buffer} containing the public key of the signer
*/
recover(msg: Buffer, sig: Buffer): Buffer {
const sigObj: elliptic.ec.SignatureOptions = this._sigFromSigBuffer(sig)
const pubk = ec.recoverPubKey(msg, sigObj, sigObj.recoveryParam)
return Buffer.from(pubk.encodeCompressed())
}
/**
* Returns the chainID associated with this key.
*
* @returns The [[KeyPair]]'s chainID
*/
getChainID(): string {
return this.chainID
}
/**
* Sets the the chainID associated with this key.
*
* @param chainID String for the chainID
*/
setChainID(chainID: string): void {
this.chainID = chainID
}
/**
* Returns the Human-Readable-Part of the network associated with this key.
*
* @returns The [[KeyPair]]'s Human-Readable-Part of the network's Bech32 addressing scheme
*/
getHRP(): string {
return this.hrp
}
/**
* Sets the the Human-Readable-Part of the network associated with this key.
*
* @param hrp String for the Human-Readable-Part of Bech32 addresses
*/
setHRP(hrp: string): void {
this.hrp = hrp
}
constructor(hrp: string, chainID: string) {
super()
this.chainID = chainID
this.hrp = hrp
this.generateKey()
}
}
/**
* Class for representing a key chain in Avalanche.
*
* @typeparam SECP256k1KeyPair Class extending [[StandardKeyPair]] which is used as the key in [[SECP256k1KeyChain]]
*/
export abstract class SECP256k1KeyChain<
SECPKPClass extends SECP256k1KeyPair
> extends StandardKeyChain<SECPKPClass> {
/**
* Makes a new key pair, returns the address.
*
* @returns Address of the new key pair
*/
makeKey: () => SECPKPClass
addKey(newKey: SECPKPClass): void {
super.addKey(newKey)
}
/**
* Given a private key, makes a new key pair, returns the address.
*
* @param privk A {@link https://github.com/feross/buffer|Buffer} or cb58 serialized string representing the private key
*
* @returns Address of the new key pair
*/
importKey: (privk: Buffer | string) => SECPKPClass
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!