From 86f2713fbc87d90b05a12d9a682a311e9ab373aa Mon Sep 17 00:00:00 2001 From: frankie Date: Wed, 11 Dec 2024 13:46:15 -1000 Subject: [PATCH 1/8] wip: changing the out put of sign. i still need to update tests --- src/index.ts | 4 ++-- src/signing/index.ts | 27 +++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8dbb878c..e64fe466 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,7 +2,7 @@ import { ApiPromise } from '@polkadot/api' import xtend from 'xtend' import { createSubstrate, isValidSubstrateAddress as isDeployer } from './utils' import RegistrationManager, { RegistrationParams } from './registration' -import SignatureRequestManager, { SigOps, SigWithAdaptersOps } from './signing' +import SignatureRequestManager, { SigOps, SigWithAdaptersOps, SignatureData } from './signing' import { crypto, loadCryptoLib } from './utils/crypto' import { Adapter } from './signing/adapters/types' import ProgramManager from './programs' @@ -203,7 +203,7 @@ export default class Entropy { * @throws {Error} If there's an error in the signing routine. */ - async sign (params: SigOps): Promise { + async sign (params: SigOps): Promise { await this.ready return this.signingManager.sign(params) } diff --git a/src/signing/index.ts b/src/signing/index.ts index 34ccc6e4..822df08e 100644 --- a/src/signing/index.ts +++ b/src/signing/index.ts @@ -8,6 +8,20 @@ import { crypto } from '../utils/crypto' import { CryptoLib } from '../utils/crypto/types' import Keyring from '../keys' +/** + * Represents a signed message and the associated data. + */ +export interface SignatureData { + signarure: string + verifyingKey: string + hashingAlogrithm: string + messageHash: string +} + +//preemptive typing for adapters +export interface AdaptedSignatureData extends SignatureData { + messageParams: any // the original object or message +} /** * Represents an encrypted message for transaction requests. */ @@ -15,7 +29,6 @@ export interface EncMsg { msg: string url: string tss_account: string - // signature_verifying_key: number[] } @@ -193,7 +206,7 @@ export default class SignatureRequestManager { hash, auxiliaryData, signatureVerifyingKey: signatureVerifyingKeyOverwrite, - }: SigOps): Promise { + }: SigOps): Promise { const strippedsigRequestHash = stripHexPrefix(sigRequestHash) // @ts-ignore: next line const validators: string[] = (await this.substrate.query.session.validators()).toHuman() @@ -219,8 +232,14 @@ export default class SignatureRequestManager { const message: EncMsg = await this.formatTxRequest(txRequest) const sigs = await this.submitTransactionRequest(message) - const sig = await this.#verifyAndPick(sigs, signingCommittee) - return Uint8Array.from(atob(sig), (c) => c.charCodeAt(0)) + const base64Sig = await this.#verifyAndPick(sigs, signingCommittee) + const buffSig = Buffer.from(base64Sig, 'base64') + return { + signarure: buffSig.toString('hex'), + hashingAlogrithm: hash, + verifyingKey: signatureVerifyingKey, + messageHash: sigRequestHash + } } /** From 0a0d1483300ab0a5284dd33aa1e95d208f6f555b Mon Sep 17 00:00:00 2001 From: frankie Date: Mon, 16 Dec 2024 10:20:54 -1000 Subject: [PATCH 2/8] breaking change: sigRequestHash -> hexMessage to be more clear about what it is. it should be a hex encode string of the message you wish to sign --- README.md | 4 +-- src/signing/adapters/base.ts | 6 ++-- src/signing/adapters/device-key-proxy.ts | 6 ++-- src/signing/adapters/noop.ts | 6 ++-- src/signing/adapters/types.ts | 2 +- src/signing/index.ts | 38 ++++++++++++------------ src/utils/index.ts | 15 ++++++++++ tests/end-to-end.test.ts | 11 +++---- tests/sign.test.ts | 24 ++++++++------- 9 files changed, 66 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 6aff640a..0a037fd5 100644 --- a/README.md +++ b/README.md @@ -378,7 +378,7 @@ const verifyingKey = await entropy.getVerifyingKey(address) // signing manager await entropy.signingManager.sign({ - sigRequestHash, + hexMessage, hash: this.adapters[type].hash, type, }) @@ -469,7 +469,7 @@ Will throw an error if the transaction type does not have a corresponding adapte // signing manager await entropy.signingManager.sign({ - sigRequestHash, + hexMessage, hash: this.adapters[type].hash, type, }) diff --git a/src/signing/adapters/base.ts b/src/signing/adapters/base.ts index 1fedd9dd..cbad7b01 100644 --- a/src/signing/adapters/base.ts +++ b/src/signing/adapters/base.ts @@ -41,7 +41,7 @@ export const PROGRAM_INTERFACE = { export const ADAPTER_PROGRAMS = [PROGRAM_INTERFACE] export interface PreSignResult extends PRESIGN_RESULT { - sigRequestHash: HexString + hexMessage: HexString auxilary_data: [AuxData] } @@ -52,9 +52,9 @@ export async function preSign( const stringMessage = JSON.stringify(message) // un comment for device key signature: // const signedMessage = deviceKey.pair.sign(stringMessage) - const sigRequestHash = toHex(stringMessage) + const hexMessage = toHex(stringMessage) - return { sigRequestHash, auxilary_data: PROGRAM_INTERFACE.auxilary_data } + return { hexMessage, auxilary_data: PROGRAM_INTERFACE.auxilary_data } } export const type = 'noop' diff --git a/src/signing/adapters/device-key-proxy.ts b/src/signing/adapters/device-key-proxy.ts index cd4e3e55..05e40dbe 100644 --- a/src/signing/adapters/device-key-proxy.ts +++ b/src/signing/adapters/device-key-proxy.ts @@ -47,7 +47,7 @@ export const DEVICE_KEY_PROXY_PROGRAM_INTERFACE = { // export const ADAPTER_PROGRAMS = [DEVICE_KEY_PROXY_PROGRAM_INTERFACE] export interface PreSignResult extends PRESIGN_RESULT { - sigRequestHash: HexString + hexMessage: HexString auxilary_data: [AuxData] } @@ -57,7 +57,7 @@ export async function preSign ( ): Promise { const stringMessage = JSON.stringify(message) const signedMessage = deviceKey.pair.sign(stringMessage) - const sigRequestHash = toHex(stringMessage) + const hexMessage = toHex(stringMessage) const convertedSig = btoa(String.fromCharCode.apply(null, signedMessage)) // Base64 encoded string @@ -75,7 +75,7 @@ export async function preSign ( }, ] - return { sigRequestHash, auxilary_data } + return { hexMessage, auxilary_data } } export const type = 'deviceKeyProxy' diff --git a/src/signing/adapters/noop.ts b/src/signing/adapters/noop.ts index 166e10d0..10bb2836 100644 --- a/src/signing/adapters/noop.ts +++ b/src/signing/adapters/noop.ts @@ -26,7 +26,7 @@ export const PROGRAM_INTERFACE = { export const ADAPTER_PROGRAMS = [PROGRAM_INTERFACE] export interface PreSignResult extends PRESIGN_RESULT { - sigRequestHash: HexString + hexMessage: HexString auxilary_data: NoopAuxData[] } @@ -37,9 +37,9 @@ export async function preSign ( const stringMessage = JSON.stringify(message) // un comment for device key signature: // const signedMessage = deviceKey.pair.sign(stringMessage) - const sigRequestHash = toHex(stringMessage) + const hexMessage = toHex(stringMessage) - return { sigRequestHash, auxilary_data: PROGRAM_INTERFACE.auxilary_data } + return { hexMessage, auxilary_data: PROGRAM_INTERFACE.auxilary_data } } export const type = 'noop' diff --git a/src/signing/adapters/types.ts b/src/signing/adapters/types.ts index d173ca99..7e2ed454 100644 --- a/src/signing/adapters/types.ts +++ b/src/signing/adapters/types.ts @@ -15,7 +15,7 @@ export interface AUX_DATA { * and auxiliary data. */ export interface PRESIGN_RESULT { - sigRequestHash: HexString + hexMessage: HexString auxilary_data: AUX_DATA[] | unknown[] } diff --git a/src/signing/index.ts b/src/signing/index.ts index 822df08e..2e3f71ef 100644 --- a/src/signing/index.ts +++ b/src/signing/index.ts @@ -3,7 +3,7 @@ import { Signer } from '../keys/types/internal' import { defaultAdapters } from './adapters/default' import { Adapter } from './adapters/types' import { ValidatorInfo } from '../types/internal' -import { stripHexPrefix, sendHttpPost, toHex, } from '../utils' +import { stripHexPrefix, addHexPrefix, sendHttpPost, toHex, } from '../utils' import { crypto } from '../utils/crypto' import { CryptoLib } from '../utils/crypto/types' import Keyring from '../keys' @@ -12,10 +12,10 @@ import Keyring from '../keys' * Represents a signed message and the associated data. */ export interface SignatureData { - signarure: string + signature: string verifyingKey: string hashingAlogrithm: string - messageHash: string + message: string // hex string as bytes? } //preemptive typing for adapters @@ -55,7 +55,7 @@ export interface SigWithAdaptersOps extends SigMsgOps { } export interface SigOps { - sigRequestHash: string + hexMessage: string hash: string type?: string auxiliaryData?: unknown[] @@ -166,7 +166,7 @@ export default class SignatureRequestManager { } return agg }, []) - // this is the named keys we care about from post sign. { sigRequestHash, auxilary_data } + // this is the named keys we care about from post sign. { hexMessage, auxilary_data } const results = await Promise.all( adaptersToRun.map((adapter) => { return adapter.preSign(this.signer, msg) @@ -179,10 +179,10 @@ export default class SignatureRequestManager { }) // flatten const auxiliaryData = [].concat(...auxiliaryDataCollection) - // grab the first sigRequestHash - const { sigRequestHash } = results[0] + // grab the first hexMessage + const { hexMessage } = results[0] const signature = await this.sign({ - sigRequestHash, + hexMessage, hash: adaptersToRun[0].HASHING_ALGORITHM, auxiliaryData, signatureVerifyingKey, @@ -194,7 +194,7 @@ export default class SignatureRequestManager { * Signs a given signature request hash. * * @param {SigOps} sigOps - Parameters for the signature operation. - * @param {string} sigOps.sigRequestHash - The hash of the signature request to be signed. + * @param {string} sigOps.hexMessage - The hash of the signature request to be signed. * @param {string} sigOps.hash - The name of the hashing algorithm used to hash the signature. * @param {unknown[]} sigOps.auxilaryData - Additional data for the signature operation. * @param {signatureVerifyingKey} sigOps.signatureVerifyingKey - The verifying key for the signature requested @@ -202,12 +202,12 @@ export default class SignatureRequestManager { */ async sign ({ - sigRequestHash, + hexMessage, hash, auxiliaryData, signatureVerifyingKey: signatureVerifyingKeyOverwrite, }: SigOps): Promise { - const strippedsigRequestHash = stripHexPrefix(sigRequestHash) + const strippedHexMessage = stripHexPrefix(hexMessage) // @ts-ignore: next line const validators: string[] = (await this.substrate.query.session.validators()).toHuman() // @ts-ignore: next line @@ -223,7 +223,7 @@ export default class SignatureRequestManager { const signatureVerifyingKey = signatureVerifyingKeyOverwrite || this.verifyingKey const txRequest = { - strippedsigRequestHash, + strippedHexMessage, auxiliaryData, validator: validatorInfo, hash, @@ -235,10 +235,10 @@ export default class SignatureRequestManager { const base64Sig = await this.#verifyAndPick(sigs, signingCommittee) const buffSig = Buffer.from(base64Sig, 'base64') return { - signarure: buffSig.toString('hex'), + signature: addHexPrefix(buffSig.toString('hex')), hashingAlogrithm: hash, verifyingKey: signatureVerifyingKey, - messageHash: sigRequestHash + message: hexMessage, } } @@ -258,7 +258,7 @@ export default class SignatureRequestManager { * Generates transaction requests formatted for validators. * * @param {object} params - Parameters for generating the transaction request. - * @param {string} params.strippedsigRequestHash - Stripped signature request hash. + * @param {string} params.strippedHexMessage - Stripped signature request hash. * @param {unknown[]} [params.auxiliaryData] - Additional data for the transaction request. * @param {ValidatorInfo[]} params.validatorsInfo - Information about the validators. * @param {string} [params.hash] - The hash type. @@ -267,20 +267,20 @@ export default class SignatureRequestManager { */ async formatTxRequest ({ - strippedsigRequestHash, + strippedHexMessage, auxiliaryData, validator, hash, signatureVerifyingKey, }: { - strippedsigRequestHash: string + strippedHexMessage: string auxiliaryData?: unknown[] validator: ValidatorInfo hash?: string signatureVerifyingKey: string }): Promise { const txRequestData: UserSignatureRequest = { - message: stripHexPrefix(strippedsigRequestHash), + message: stripHexPrefix(strippedHexMessage), auxilary_data: auxiliaryData, block_number: await this.getBlockNumber(), hash, @@ -337,7 +337,7 @@ export default class SignatureRequestManager { /** * Selects validators based on the signature request. * - * @param {string} sigRequest - The signature request hash. + * @param {string} hexMessage - The signature request hash. * @returns {Promise} A promise resolving to an array of validator information. */ diff --git a/src/utils/index.ts b/src/utils/index.ts index 99ae1d7d..03345417 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -43,6 +43,21 @@ export function stripHexPrefix (str: string): string { return str } +/** + * Removes the '0x' prefix from a hexadecimal string if it exists. + * + * @param {string} str - The hexadecimal string. + * @returns {string} The string without the '0x' prefix. + */ + +export function addHexPrefix (str: string): string { + if (typeof str === 'string') { + if (str.startsWith('0x')) return str + return `0x${str}` + } + throw new TypeError('not a string') +} + /** * Validates whether a given address is a valid Substrate address. * diff --git a/tests/end-to-end.test.ts b/tests/end-to-end.test.ts index 403b63c6..72e91edd 100644 --- a/tests/end-to-end.test.ts +++ b/tests/end-to-end.test.ts @@ -170,7 +170,7 @@ test('End To End', async (t) => { const msgParam: MsgParams = { msg } - const signatureFromAdapter = await run( + const signatureDataFromAdapter = await run( 'signWithAdaptersInOrder', entropy.signWithAdaptersInOrder({ msg: msgParam, @@ -179,7 +179,7 @@ test('End To End', async (t) => { ) t.equal( - util.u8aToHex(signatureFromAdapter).length, + signatureDataFromAdapter.signature.length, 132, 'got a good sig from adapter' ) @@ -197,14 +197,15 @@ test('End To End', async (t) => { entropy.programs.get(verifyingKey) ) t.equal(programsAftreRemoveDefault.length, 1, 'eve has 1 program') - const signature = await run( + const signatureData = await run( 'sign', entropy.sign({ - sigRequestHash: msg, + hexMessage: msg, hash: 'sha3', }) ) - t.equal(util.u8aToHex(signature).length, 132, 'got a good sig') + console.log(signatureData) + t.equal(signatureData.signature.length, 132, 'got a good sig') t.end() }) diff --git a/tests/sign.test.ts b/tests/sign.test.ts index 932d3716..fe6b53d3 100644 --- a/tests/sign.test.ts +++ b/tests/sign.test.ts @@ -48,16 +48,20 @@ test('Sign', async (t) => { /* Sign */ - const signature = await run( + const signatureData = await run( 'sign', entropy.signWithAdaptersInOrder({ msg: { msg }, order: ['deviceKeyProxy'], }) ) - - t.true(signature && signature.length > 32, 'signature has some body!') - signature && console.log(signature) + t.true(!!signatureData, 'signatureData exists') + t.true('signature' in signatureData, 'signatureData.signature exists') + t.true('verifyingKey' in signatureData, 'signatureData.verifyingKey exists') + t.true('hashingAlgorith' in signatureData, 'signatureData.hashingAlgorith exists') + t.true('message' in signatureData, 'signatureData.message exists') + t.true(signatureData.signature.length > 32, 'signature has some body!') + signatureData && console.log(signatureData) t.end() }) @@ -74,7 +78,7 @@ test('Sign: Long Message', async t => { Adding some symbols for good measure: #$@%@#$@#%#@`; - const signature = await run( + const signatureData = await run( 'sign', entropy.signWithAdaptersInOrder({ msg: { msg: dummyLongMessage }, @@ -82,8 +86,8 @@ test('Sign: Long Message', async t => { }) ) - t.true(signature && signature.length > 32, 'signature has some body!') - signature && console.log(signature) + t.true(signatureData.signature.length > 32, 'signature has some body!') + signatureData && console.log(signatureData) t.end() }) @@ -147,7 +151,7 @@ test('Sign: custom signatureVerifyingKey', async (t) => { t.notEqual(signatureVerifyingKey, eveEntropy.signingManager.verifyingKey, 'choose non-default signatureVerifyingKey') - const signature = await run( + const signatureData = await run( 'sign', eveEntropy.signWithAdaptersInOrder({ msg: { msg }, @@ -156,8 +160,8 @@ test('Sign: custom signatureVerifyingKey', async (t) => { }) ) - t.true(signature && signature.length > 32, 'signature has some body!') - signature && console.log(signature) + t.true(signatureData.signature.length > 32, 'signature has some body!') + signatureData && console.log(signatureData) t.end() }) From b95b4f263de5879470907a955f64578fe35cd16a Mon Sep 17 00:00:00 2001 From: frankie Date: Mon, 16 Dec 2024 10:24:21 -1000 Subject: [PATCH 3/8] remove console.log --- tests/end-to-end.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/end-to-end.test.ts b/tests/end-to-end.test.ts index 72e91edd..61ed918b 100644 --- a/tests/end-to-end.test.ts +++ b/tests/end-to-end.test.ts @@ -204,7 +204,6 @@ test('End To End', async (t) => { hash: 'sha3', }) ) - console.log(signatureData) t.equal(signatureData.signature.length, 132, 'got a good sig') t.end() From 84b3c3979f9276bcd7fc8ffa074de167d54ae3f7 Mon Sep 17 00:00:00 2001 From: frankie Date: Mon, 16 Dec 2024 10:25:49 -1000 Subject: [PATCH 4/8] addHexPrefix to signatureData message --- src/signing/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/signing/index.ts b/src/signing/index.ts index 2e3f71ef..76dc2c03 100644 --- a/src/signing/index.ts +++ b/src/signing/index.ts @@ -238,7 +238,7 @@ export default class SignatureRequestManager { signature: addHexPrefix(buffSig.toString('hex')), hashingAlogrithm: hash, verifyingKey: signatureVerifyingKey, - message: hexMessage, + message: addHexPrefix(hexMessage), } } From 85a019ea2e4ee504ebd7c9890dfb11d982a8eecb Mon Sep 17 00:00:00 2001 From: frankie Date: Mon, 16 Dec 2024 10:27:02 -1000 Subject: [PATCH 5/8] fix spelling in test --- tests/sign.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sign.test.ts b/tests/sign.test.ts index fe6b53d3..4736f72e 100644 --- a/tests/sign.test.ts +++ b/tests/sign.test.ts @@ -58,7 +58,7 @@ test('Sign', async (t) => { t.true(!!signatureData, 'signatureData exists') t.true('signature' in signatureData, 'signatureData.signature exists') t.true('verifyingKey' in signatureData, 'signatureData.verifyingKey exists') - t.true('hashingAlgorith' in signatureData, 'signatureData.hashingAlgorith exists') + t.true('hashingAlogrithm' in signatureData, 'signatureData.hashingAlgorith exists') t.true('message' in signatureData, 'signatureData.message exists') t.true(signatureData.signature.length > 32, 'signature has some body!') signatureData && console.log(signatureData) From 48843aa26f2fd3bbe3b68a20cb7830a047318962 Mon Sep 17 00:00:00 2001 From: frankie Date: Mon, 16 Dec 2024 10:45:56 -1000 Subject: [PATCH 6/8] CHANGELOG.md updated for issues: #434 && #442 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cafa5355..064b9d8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,8 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil ### Changed ### Broke - +- sign and sign with adapters no longer returns just the signature. It now returns a object `SignatureData` that contains the signature and information pronating to it see the `SignatureData` interface in (./src/signing/index.ts)(./src/signing/index.ts) +- `entropy.sign` and `entropy.signWithAdaptersInOrder` function argument interface key renamed `sigRequestHash` -> `hexMessage` ### Dev ### Meta From 79b600d1d71b397980cb3787de793c35f3c5cedc Mon Sep 17 00:00:00 2001 From: frankie Date: Wed, 18 Dec 2024 10:30:27 -1000 Subject: [PATCH 7/8] wip: verify function created still needs to be tested and brought into the signing manager --- package.json | 1 + src/signing/index.ts | 4 +-- src/utils/crypto/index.ts | 34 +++++++++++++++++++- tests/end-to-end.test.ts | 6 ++-- tests/sign.test.ts | 2 +- yarn.lock | 67 +++++++++++++++++++++++++++++++++------ 6 files changed, 97 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 9360d46f..59d4b147 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,7 @@ "@types/lodash.clonedeep": "^4.5.9", "@types/node": "^20.12.12", "debug": "^4.3.4", + "ethers": "^6.13.4", "hpke-js": "^1.2.7", "lodash.clonedeep": "^4.5.0", "uuid": "^9.0.1", diff --git a/src/signing/index.ts b/src/signing/index.ts index 76dc2c03..2313268c 100644 --- a/src/signing/index.ts +++ b/src/signing/index.ts @@ -14,7 +14,7 @@ import Keyring from '../keys' export interface SignatureData { signature: string verifyingKey: string - hashingAlogrithm: string + hashType: string message: string // hex string as bytes? } @@ -236,7 +236,7 @@ export default class SignatureRequestManager { const buffSig = Buffer.from(base64Sig, 'base64') return { signature: addHexPrefix(buffSig.toString('hex')), - hashingAlogrithm: hash, + hashType: hash, verifyingKey: signatureVerifyingKey, message: addHexPrefix(hexMessage), } diff --git a/src/utils/crypto/index.ts b/src/utils/crypto/index.ts index 1312d37d..78f8bb70 100644 --- a/src/utils/crypto/index.ts +++ b/src/utils/crypto/index.ts @@ -1,12 +1,15 @@ import { cryptoWaitReady, decodeAddress, + encodeAddress, signatureVerify, + blake2AsHex, } from '@polkadot/util-crypto' - +import { keccak256, SigningKey } from 'ethers' import * as polkadotCryptoUtil from '@polkadot/util-crypto' import { CryptoLib, ResObjectType } from './types' import { u8aToHex } from '@polkadot/util' +import { SignatureData, AdaptedSignatureData } from '../../signing' let cryptoLib const res: ResObjectType = { @@ -97,3 +100,32 @@ async function verifySignature ( return signatureVerify(message, signature, hexPublicKey).isValid } + +/** + * Verifies the signature of a of a signed message coming from the signing method in the entropy class. + * + * @param {@link SignatureData} - The signature data to be verified. + * @returns A Promise that resolves to a boolean indicating whether the signature is valid. + */ + +export async function verify (sigData: SignatureData | AdaptedSignatureData): Promise { + const { hashType, message, verifyingKey, signature } = sigData + + if (!hashType) throw new Error('hashType not include in the signature data') + if (!message) throw new Error('message not include in the signature data') + if (!verifyingKey) throw new Error('verifyingKey not include in the signature data') + if (!signature) throw new Error('signature not include in the signature data') + + + if (hashType.toLowerCase() === 'keccak') { + const recoveredPk = SigningKey.recoverPublicKey(keccak256(message), signature) + return recoveredPk === SigningKey.computePublicKey(verifyingKey) + } + + if (hashType.toLowerCase() === 'blake2_256') { + const address = encodeAddress(blake2AsHex(verifyingKey)) + return signatureVerify(message, signature, address).isValid + } + + throw new Error(`unsupported hashType: ${hashType}`) +} diff --git a/tests/end-to-end.test.ts b/tests/end-to-end.test.ts index 61ed918b..191fa84b 100644 --- a/tests/end-to-end.test.ts +++ b/tests/end-to-end.test.ts @@ -19,7 +19,7 @@ const networkType = 'four-nodes' const msg = Buffer.from('Hello world: signature from entropy!').toString('hex') -test('End To End', async (t) => { +test.only('End To End', async (t) => { const run = promiseRunner(t) await run('network up', spinNetworkUp(networkType)) t.teardown(async () => { @@ -177,7 +177,6 @@ test('End To End', async (t) => { order: ['deviceKeyProxy', 'noop'], }) ) - t.equal( signatureDataFromAdapter.signature.length, 132, @@ -201,10 +200,11 @@ test('End To End', async (t) => { 'sign', entropy.sign({ hexMessage: msg, - hash: 'sha3', + hash: 'blake2_256', }) ) t.equal(signatureData.signature.length, 132, 'got a good sig') + console.log('signatures', signatureData, signatureDataFromAdapter) t.end() }) diff --git a/tests/sign.test.ts b/tests/sign.test.ts index 4736f72e..0259b326 100644 --- a/tests/sign.test.ts +++ b/tests/sign.test.ts @@ -58,7 +58,7 @@ test('Sign', async (t) => { t.true(!!signatureData, 'signatureData exists') t.true('signature' in signatureData, 'signatureData.signature exists') t.true('verifyingKey' in signatureData, 'signatureData.verifyingKey exists') - t.true('hashingAlogrithm' in signatureData, 'signatureData.hashingAlgorith exists') + t.true('hashType' in signatureData, 'signatureData.hashingAlgorith exists') t.true('message' in signatureData, 'signatureData.message exists') t.true(signatureData.signature.length > 32, 'signature has some body!') signatureData && console.log(signatureData) diff --git a/yarn.lock b/yarn.lock index 04ef1bc3..bed5632c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@adraffy/ens-normalize@1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== + "@ampproject/remapping@^2.2.0": version "2.3.0" resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz" @@ -576,6 +581,13 @@ resolved "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.4.1.tgz" integrity sha512-QCOA9cgf3Rc33owG0AYBB9wszz+Ul2kramWN8tXG44Gyciud/tbkEqvxRF/IpqQaBpRBNi9f4jdNxqB2CQCIXg== +"@noble/curves@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" + integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== + dependencies: + "@noble/hashes" "1.3.2" + "@noble/curves@1.3.0": version "1.3.0" resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz" @@ -590,6 +602,11 @@ dependencies: "@noble/hashes" "1.4.0" +"@noble/hashes@1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + "@noble/hashes@1.3.3": version "1.3.3" resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz" @@ -1136,6 +1153,13 @@ dependencies: undici-types "~5.26.4" +"@types/node@22.7.5": + version "22.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" + integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ== + dependencies: + undici-types "~6.19.2" + "@types/parse-json@^4.0.0": version "4.0.2" resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz" @@ -1312,6 +1336,11 @@ acorn@^8.4.1, acorn@^8.9.0: resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== +aes-js@4.0.0-beta.5: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" + integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" @@ -2289,6 +2318,19 @@ esutils@^2.0.2: resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +ethers@^6.13.4: + version "6.13.4" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.4.tgz#bd3e1c3dc1e7dc8ce10f9ffb4ee40967a651b53c" + integrity sha512-21YtnZVg4/zKkCQPjrDj38B1r4nQvTZLopUGMLQ1ePU2zV/joCfDC3t3iKQjWRzjjjbzR+mdAIoikeBRNkdllA== + dependencies: + "@adraffy/ens-normalize" "1.10.1" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@types/node" "22.7.5" + aes-js "4.0.0-beta.5" + tslib "2.7.0" + ws "8.17.1" + eventemitter3@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz" @@ -4544,6 +4586,11 @@ ts-prune@^0.10.3: "true-myth" "^4.1.0" ts-morph "^13.0.1" +tslib@2.7.0, tslib@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + tslib@^1.8.1: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" @@ -4554,11 +4601,6 @@ tslib@^2.1.0, tslib@^2.6.2: resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== -tslib@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" - integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== - tsup@^6.5.0: version "6.7.0" resolved "https://registry.npmjs.org/tsup/-/tsup-6.7.0.tgz" @@ -4716,6 +4758,11 @@ undici-types@~5.26.4: resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + update-browserslist-db@^1.0.13: version "1.0.15" resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.15.tgz" @@ -4892,16 +4939,16 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" +ws@8.17.1, ws@^8.17.1: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" + integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== + ws@^8.16.0: version "8.18.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== -ws@^8.17.1: - version "8.17.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" - integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== - ws@^8.8.1: version "8.17.0" resolved "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz" From 89c44790989cee9eb756006195b133ddbd2a54ba Mon Sep 17 00:00:00 2001 From: frankie Date: Wed, 18 Dec 2024 13:01:54 -1000 Subject: [PATCH 8/8] use verify method! --- src/index.ts | 21 ++++++++++++++++++--- src/signing/index.ts | 2 +- tests/end-to-end.test.ts | 6 +++--- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index e64fe466..4cbfcfdc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,8 +2,8 @@ import { ApiPromise } from '@polkadot/api' import xtend from 'xtend' import { createSubstrate, isValidSubstrateAddress as isDeployer } from './utils' import RegistrationManager, { RegistrationParams } from './registration' -import SignatureRequestManager, { SigOps, SigWithAdaptersOps, SignatureData } from './signing' -import { crypto, loadCryptoLib } from './utils/crypto' +import SignatureRequestManager, { SigOps, SigWithAdaptersOps, SignatureData, AdaptedSignatureData } from './signing' +import { crypto, loadCryptoLib, verify } from './utils/crypto' import { Adapter } from './signing/adapters/types' import ProgramManager from './programs' import Keyring from './keys' @@ -199,7 +199,7 @@ export default class Entropy { * It returns the signature from the first validator after validation. * * @param {SigOps} params - The signature operation parameters. - * @returns {Promise} A promise that resolves to the signed hash as a Uint8Array. + * @returns {Promise} A promise that resolves to the signed hash as a Uint8Array. * @throws {Error} If there's an error in the signing routine. */ @@ -207,6 +207,21 @@ export default class Entropy { await this.ready return this.signingManager.sign(params) } + /** + * Verifies signature data. + * This method involves various steps including validator selection, transaction request formatting, + * and submission of these requests to validators for signing. + * It returns the signature from the first validator after validation. + * + * @param {SignatureData | AdaptedSignatureData} params - The signature operation parameters. + * @returns {Promise} A promise that resolves to the signed hash as a Uint8Array. + * @throws {Error} If there's an error in the verifying routine. + */ + + async verify (params: SignatureData | AdaptedSignatureData): Promise { + await this.ready + return verify(params) + } /** * Shuts the Entropy SDK down gracefully. diff --git a/src/signing/index.ts b/src/signing/index.ts index 2313268c..9dae907e 100644 --- a/src/signing/index.ts +++ b/src/signing/index.ts @@ -20,7 +20,7 @@ export interface SignatureData { //preemptive typing for adapters export interface AdaptedSignatureData extends SignatureData { - messageParams: any // the original object or message + messageParams?: any // the original object or message } /** * Represents an encrypted message for transaction requests. diff --git a/tests/end-to-end.test.ts b/tests/end-to-end.test.ts index 191fa84b..5db25c28 100644 --- a/tests/end-to-end.test.ts +++ b/tests/end-to-end.test.ts @@ -19,7 +19,7 @@ const networkType = 'four-nodes' const msg = Buffer.from('Hello world: signature from entropy!').toString('hex') -test.only('End To End', async (t) => { +test('End To End', async (t) => { const run = promiseRunner(t) await run('network up', spinNetworkUp(networkType)) t.teardown(async () => { @@ -203,8 +203,8 @@ test.only('End To End', async (t) => { hash: 'blake2_256', }) ) - t.equal(signatureData.signature.length, 132, 'got a good sig') - console.log('signatures', signatureData, signatureDataFromAdapter) + await run('verified signature blake2_256', entropy.verify(signatureData)) + await run(`verified signature ${signatureDataFromAdapter.hashType}`, entropy.verify(signatureDataFromAdapter)) t.end() })