Skip to content

Commit

Permalink
refactor(crypto): move verifySignatures into Transactions.Verifier (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
faustbrian committed Nov 8, 2019
1 parent 7acf6cc commit 2a8fa00
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 53 deletions.
57 changes: 5 additions & 52 deletions packages/core-state/src/wallets/wallet.ts
@@ -1,14 +1,6 @@
import { State } from "@arkecosystem/core-interfaces";
import { Errors, Handlers } from "@arkecosystem/core-transactions";
import {
Crypto,
Enums,
Errors as CryptoErrors,
Identities,
Interfaces,
Transactions,
Utils,
} from "@arkecosystem/crypto";
import { Enums, Identities, Interfaces, Transactions, Utils } from "@arkecosystem/crypto";
import assert from "assert";
import dottie from "dottie";

Expand Down Expand Up @@ -116,49 +108,10 @@ export class Wallet implements State.IWallet {
transaction: Interfaces.ITransactionData,
multiSignature?: Interfaces.IMultiSignatureAsset,
): boolean {
multiSignature = multiSignature || this.getAttribute("multiSignature");
if (!multiSignature) {
throw new Errors.InvalidMultiSignatureError();
}

const { publicKeys, min }: Interfaces.IMultiSignatureAsset = multiSignature;
const { signatures }: Interfaces.ITransactionData = transaction;

const hash: Buffer = Transactions.Utils.toHash(transaction, {
excludeSignature: true,
excludeSecondSignature: true,
excludeMultiSignature: true,
});

const publicKeyIndexes: { [index: number]: boolean } = {};
let verified: boolean = false;
let verifiedSignatures: number = 0;
for (let i = 0; i < signatures.length; i++) {
const signature: string = signatures[i];
const publicKeyIndex: number = parseInt(signature.slice(0, 2), 16);

if (!publicKeyIndexes[publicKeyIndex]) {
publicKeyIndexes[publicKeyIndex] = true;
} else {
throw new CryptoErrors.DuplicateParticipantInMultiSignatureError();
}

const partialSignature: string = signature.slice(2, 130);
const publicKey: string = publicKeys[publicKeyIndex];

if (Crypto.Hash.verifySchnorr(hash, partialSignature, publicKey)) {
verifiedSignatures++;
}

if (verifiedSignatures === min) {
verified = true;
break;
} else if (signatures.length - (i + 1 - verifiedSignatures) < min) {
break;
}
}

return verified;
return Transactions.Verifier.verifySignatures(
transaction,
multiSignature || this.getAttribute("multiSignature"),
);
}

/**
Expand Down
48 changes: 47 additions & 1 deletion packages/crypto/src/transactions/verifier.ts
@@ -1,5 +1,6 @@
import { Hash } from "../crypto/hash";
import { ISchemaValidationResult, ITransactionData } from "../interfaces";
import { DuplicateParticipantInMultiSignatureError, InvalidMultiSignatureAssetError } from "../errors";
import { IMultiSignatureAsset, ISchemaValidationResult, ITransactionData } from "../interfaces";
import { configManager } from "../managers";
import { isException } from "../utils";
import { validator } from "../validation";
Expand Down Expand Up @@ -30,6 +31,51 @@ export class Verifier {
return this.internalVerifySignature(hash, secondSignature, publicKey);
}

public static verifySignatures(transaction: ITransactionData, multiSignature: IMultiSignatureAsset): boolean {
if (!multiSignature) {
throw new InvalidMultiSignatureAssetError();
}

const { publicKeys, min }: IMultiSignatureAsset = multiSignature;
const { signatures }: ITransactionData = transaction;

const hash: Buffer = Utils.toHash(transaction, {
excludeSignature: true,
excludeSecondSignature: true,
excludeMultiSignature: true,
});

const publicKeyIndexes: { [index: number]: boolean } = {};
let verified: boolean = false;
let verifiedSignatures: number = 0;
for (let i = 0; i < signatures.length; i++) {
const signature: string = signatures[i];
const publicKeyIndex: number = parseInt(signature.slice(0, 2), 16);

if (!publicKeyIndexes[publicKeyIndex]) {
publicKeyIndexes[publicKeyIndex] = true;
} else {
throw new DuplicateParticipantInMultiSignatureError();
}

const partialSignature: string = signature.slice(2, 130);
const publicKey: string = publicKeys[publicKeyIndex];

if (Hash.verifySchnorr(hash, partialSignature, publicKey)) {
verifiedSignatures++;
}

if (verifiedSignatures === min) {
verified = true;
break;
} else if (signatures.length - (i + 1 - verifiedSignatures) < min) {
break;
}
}

return verified;
}

public static verifyHash(data: ITransactionData): boolean {
const { signature, senderPublicKey } = data;

Expand Down

0 comments on commit 2a8fa00

Please sign in to comment.