@aptos-labs/ts-sdk
Version:
Aptos TypeScript SDK
1 lines • 11.5 kB
Source Map (JSON)
{"version":3,"sources":["../../src/core/crypto/secp256k1.ts"],"sourcesContent":["// Copyright © Aptos Foundation\n// SPDX-License-Identifier: Apache-2.0\n\nimport { sha3_256 } from \"@noble/hashes/sha3\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { HDKey } from \"@scure/bip32\";\nimport { Serializable, Deserializer, Serializer } from \"../../bcs\";\nimport { Hex } from \"../hex\";\nimport { HexInput } from \"../../types\";\nimport { isValidBIP44Path, mnemonicToSeed } from \"./hdKey\";\nimport { PrivateKey } from \"./privateKey\";\nimport { PublicKey, VerifySignatureArgs } from \"./publicKey\";\nimport { Signature } from \"./signature\";\nimport { convertSigningMessage } from \"./utils\";\n\n/**\n * Represents the Secp256k1 ecdsa public key\n *\n * Secp256k1 authentication key is represented in the SDK as `AnyPublicKey`.\n */\nexport class Secp256k1PublicKey extends PublicKey {\n // Secp256k1 ecdsa public keys contain a prefix indicating compression and two 32-byte coordinates.\n static readonly LENGTH: number = 65;\n\n // Hex value of the public key\n private readonly key: Hex;\n\n /**\n * Create a new PublicKey instance from a Uint8Array or String.\n *\n * @param hexInput A HexInput (string or Uint8Array)\n */\n constructor(hexInput: HexInput) {\n super();\n\n const hex = Hex.fromHexInput(hexInput);\n if (hex.toUint8Array().length !== Secp256k1PublicKey.LENGTH) {\n throw new Error(`PublicKey length should be ${Secp256k1PublicKey.LENGTH}`);\n }\n this.key = hex;\n }\n\n // region PublicKey\n /**\n * Verifies a Secp256k1 signature against the public key\n *\n * Note signatures are validated to be canonical as a malleability check\n */\n verifySignature(args: VerifySignatureArgs): boolean {\n const { message, signature } = args;\n if (!(signature instanceof Secp256k1Signature)) {\n return false;\n }\n const messageToVerify = convertSigningMessage(message);\n const messageBytes = Hex.fromHexInput(messageToVerify).toUint8Array();\n const messageSha3Bytes = sha3_256(messageBytes);\n const signatureBytes = signature.toUint8Array();\n return secp256k1.verify(signatureBytes, messageSha3Bytes, this.key.toUint8Array(), { lowS: true });\n }\n\n toUint8Array(): Uint8Array {\n return this.key.toUint8Array();\n }\n\n // endregion\n\n // region Serializable\n\n serialize(serializer: Serializer): void {\n serializer.serializeBytes(this.key.toUint8Array());\n }\n\n static deserialize(deserializer: Deserializer): Secp256k1PublicKey {\n const bytes = deserializer.deserializeBytes();\n return new Secp256k1PublicKey(bytes);\n }\n\n // endregion\n\n /**\n * @deprecated use `instanceof Secp256k1PublicKey` instead\n * @param publicKey\n */\n static isPublicKey(publicKey: PublicKey): publicKey is Secp256k1PublicKey {\n return publicKey instanceof Secp256k1PublicKey;\n }\n}\n\n/**\n * A Secp256k1 ecdsa private key\n */\nexport class Secp256k1PrivateKey extends Serializable implements PrivateKey {\n /**\n * Length of Secp256k1 ecdsa private key\n */\n static readonly LENGTH: number = 32;\n\n /**\n * The private key bytes\n * @private\n */\n private readonly key: Hex;\n\n // region Constructors\n\n /**\n * Create a new PrivateKey instance from a Uint8Array or String.\n *\n * @param hexInput A HexInput (string or Uint8Array)\n */\n constructor(hexInput: HexInput) {\n super();\n\n const privateKeyHex = Hex.fromHexInput(hexInput);\n if (privateKeyHex.toUint8Array().length !== Secp256k1PrivateKey.LENGTH) {\n throw new Error(`PrivateKey length should be ${Secp256k1PrivateKey.LENGTH}`);\n }\n\n this.key = privateKeyHex;\n }\n\n /**\n * Generate a new random private key.\n *\n * @returns Secp256k1PrivateKey\n */\n static generate(): Secp256k1PrivateKey {\n const hexInput = secp256k1.utils.randomPrivateKey();\n return new Secp256k1PrivateKey(hexInput);\n }\n\n /**\n * Derives a private key from a mnemonic seed phrase.\n *\n * @param path the BIP44 path\n * @param mnemonics the mnemonic seed phrase\n *\n * @returns The generated key\n */\n static fromDerivationPath(path: string, mnemonics: string): Secp256k1PrivateKey {\n if (!isValidBIP44Path(path)) {\n throw new Error(`Invalid derivation path ${path}`);\n }\n return Secp256k1PrivateKey.fromDerivationPathInner(path, mnemonicToSeed(mnemonics));\n }\n\n /**\n * A private inner function so we can separate from the main fromDerivationPath() method\n * to add tests to verify we create the keys correctly.\n *\n * @param path the BIP44 path\n * @param seed the seed phrase created by the mnemonics\n *\n * @returns The generated key\n */\n private static fromDerivationPathInner(path: string, seed: Uint8Array): Secp256k1PrivateKey {\n const { privateKey } = HDKey.fromMasterSeed(seed).derive(path);\n // library returns privateKey as Uint8Array | null\n if (privateKey === null) {\n throw new Error(\"Invalid key\");\n }\n\n return new Secp256k1PrivateKey(privateKey);\n }\n\n // endregion\n\n // region PrivateKey\n\n /**\n * Sign the given message with the private key.\n *\n * Note: signatures are canonical, and non-malleable\n *\n * @param message a message as a string or Uint8Array\n * @returns Signature\n */\n sign(message: HexInput): Secp256k1Signature {\n const messageToSign = convertSigningMessage(message);\n const messageBytes = Hex.fromHexInput(messageToSign);\n const messageHashBytes = sha3_256(messageBytes.toUint8Array());\n const signature = secp256k1.sign(messageHashBytes, this.key.toUint8Array(), { lowS: true });\n return new Secp256k1Signature(signature.toCompactRawBytes());\n }\n\n /**\n * Derive the Secp256k1PublicKey from this private key.\n *\n * @returns Secp256k1PublicKey\n */\n publicKey(): Secp256k1PublicKey {\n const bytes = secp256k1.getPublicKey(this.key.toUint8Array(), false);\n return new Secp256k1PublicKey(bytes);\n }\n\n /**\n * Get the private key in bytes (Uint8Array).\n *\n * @returns\n */\n toUint8Array(): Uint8Array {\n return this.key.toUint8Array();\n }\n\n /**\n * Get the private key as a hex string with the 0x prefix.\n *\n * @returns string representation of the private key\n */\n toString(): string {\n return this.key.toString();\n }\n\n // endregion\n\n // region Serializable\n\n serialize(serializer: Serializer): void {\n serializer.serializeBytes(this.toUint8Array());\n }\n\n static deserialize(deserializer: Deserializer): Secp256k1PrivateKey {\n const bytes = deserializer.deserializeBytes();\n return new Secp256k1PrivateKey(bytes);\n }\n\n // endregion\n\n /**\n * @deprecated use `instanceof Secp256k1PrivateKey` instead\n */\n static isPrivateKey(privateKey: PrivateKey): privateKey is Secp256k1PrivateKey {\n return privateKey instanceof Secp256k1PrivateKey;\n }\n}\n\n/**\n * A signature of a message signed using a Secp256k1 ecdsa private key\n */\nexport class Secp256k1Signature extends Signature {\n /**\n * Secp256k1 ecdsa signatures are 256-bit.\n */\n static readonly LENGTH = 64;\n\n /**\n * The signature bytes\n * @private\n */\n private readonly data: Hex;\n\n // region Constructors\n\n /**\n * Create a new Signature instance from a Uint8Array or String.\n *\n * @param hexInput A HexInput (string or Uint8Array)\n */\n constructor(hexInput: HexInput) {\n super();\n const data = Hex.fromHexInput(hexInput);\n if (data.toUint8Array().length !== Secp256k1Signature.LENGTH) {\n throw new Error(\n `Signature length should be ${Secp256k1Signature.LENGTH}, received ${data.toUint8Array().length}`,\n );\n }\n this.data = data;\n }\n\n // endregion\n\n // region Signature\n\n toUint8Array(): Uint8Array {\n return this.data.toUint8Array();\n }\n\n // endregion\n\n // region Serializable\n\n serialize(serializer: Serializer): void {\n serializer.serializeBytes(this.data.toUint8Array());\n }\n\n static deserialize(deserializer: Deserializer): Secp256k1Signature {\n const hex = deserializer.deserializeBytes();\n return new Secp256k1Signature(hex);\n }\n\n // endregion\n}\n"],"mappings":"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","names":["sha3_256","secp256k1","HDKey","_Secp256k1PublicKey","PublicKey","hexInput","hex","Hex","args","message","signature","Secp256k1Signature","messageToVerify","convertSigningMessage","messageBytes","messageSha3Bytes","sha3_256","signatureBytes","secp256k1","serializer","deserializer","bytes","publicKey","Secp256k1PublicKey","_Secp256k1PrivateKey","Serializable","privateKeyHex","path","mnemonics","isValidBIP44Path","mnemonicToSeed","seed","privateKey","HDKey","messageToSign","messageHashBytes","Secp256k1PrivateKey","_Secp256k1Signature","Signature","data"]}