Add verifyMultipleSignatures method
This commit is contained in:
parent
e8d81fef96
commit
a8f7256fcd
|
@ -28,6 +28,14 @@ export class Signature implements ISignature {
|
|||
return new Signature(agg.toSignature());
|
||||
}
|
||||
|
||||
static verifyMultipleSignatures(publicKeys: PublicKey[], messages: Uint8Array[], signatures: Signature[]): boolean {
|
||||
return blst.verifyMultipleAggregateSignatures(
|
||||
messages,
|
||||
publicKeys.map((publicKey) => publicKey.affine),
|
||||
signatures.map((signature) => signature.affine)
|
||||
);
|
||||
}
|
||||
|
||||
verify(publicKey: PublicKey, message: Uint8Array): boolean {
|
||||
// Individual infinity signatures are NOT okay. Aggregated signatures MAY be infinity
|
||||
if (this.affine.value.is_inf()) {
|
||||
|
|
|
@ -106,6 +106,36 @@ export function functionalInterfaceFactory({
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies multiple signatures at once returning true if all valid or false
|
||||
* if at least one is not. Optimized method when knowing which signature is
|
||||
* wrong is not relevant, i.e. verifying an Eth2.0 block.
|
||||
* https://ethresear.ch/t/fast-verification-of-multiple-bls-signatures/5407
|
||||
*/
|
||||
function verifyMultipleSignatures(
|
||||
publicKeys: Uint8Array[],
|
||||
messages: Uint8Array[],
|
||||
signatures: Uint8Array[]
|
||||
): boolean {
|
||||
validateBytes(publicKeys, "publicKey");
|
||||
validateBytes(messages, "message");
|
||||
validateBytes(signatures, "signatures");
|
||||
|
||||
if (publicKeys.length === 0 || publicKeys.length !== messages.length || publicKeys.length !== signatures.length) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return Signature.verifyMultipleSignatures(
|
||||
publicKeys.map((publicKey) => PublicKey.fromBytes(publicKey)),
|
||||
messages.map((msg) => msg),
|
||||
signatures.map((signature) => Signature.fromBytes(signature))
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof NotInitializedError) throw e;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a public key from a secret key
|
||||
*/
|
||||
|
@ -121,6 +151,7 @@ export function functionalInterfaceFactory({
|
|||
verify,
|
||||
verifyAggregate,
|
||||
verifyMultiple,
|
||||
verifyMultipleSignatures,
|
||||
secretKeyToPublicKey,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {SIGNATURE_LENGTH} from "../constants";
|
||||
import {SignatureType} from "bls-eth-wasm";
|
||||
import {SignatureType, multiVerify} from "bls-eth-wasm";
|
||||
import {getContext} from "./context";
|
||||
import {PublicKey} from "./publicKey";
|
||||
import {bytesToHex, hexToBytes, isZeroUint8Array} from "../helpers";
|
||||
|
@ -45,6 +45,14 @@ export class Signature implements ISignature {
|
|||
return new Signature(signature);
|
||||
}
|
||||
|
||||
static verifyMultipleSignatures(publicKeys: PublicKey[], messages: Uint8Array[], signatures: Signature[]): boolean {
|
||||
return multiVerify(
|
||||
publicKeys.map((publicKey) => publicKey.value),
|
||||
signatures.map((signature) => signature.value),
|
||||
messages
|
||||
);
|
||||
}
|
||||
|
||||
verify(publicKey: PublicKey, message: Uint8Array): boolean {
|
||||
return publicKey.value.verify(this.value, message);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ export interface IBls {
|
|||
fromBytes(bytes: Uint8Array): Signature;
|
||||
fromHex(hex: string): Signature;
|
||||
aggregate(signatures: Signature[]): Signature;
|
||||
verifyMultipleSignatures(publicKeys: PublicKey[], messages: Uint8Array[], signatures: Signature[]): boolean;
|
||||
};
|
||||
|
||||
sign(secretKey: Uint8Array, message: Uint8Array): Uint8Array;
|
||||
|
@ -21,6 +22,7 @@ export interface IBls {
|
|||
verify(publicKey: Uint8Array, message: Uint8Array, signature: Uint8Array): boolean;
|
||||
verifyAggregate(publicKeys: Uint8Array[], message: Uint8Array, signature: Uint8Array): boolean;
|
||||
verifyMultiple(publicKeys: Uint8Array[], messages: Uint8Array[], signature: Uint8Array): boolean;
|
||||
verifyMultipleSignatures(publicKeys: Uint8Array[], messages: Uint8Array[], signatures: Uint8Array[]): boolean;
|
||||
secretKeyToPublicKey(secretKey: Uint8Array): Uint8Array;
|
||||
|
||||
init(): Promise<void>;
|
||||
|
@ -49,6 +51,7 @@ export declare class Signature {
|
|||
static fromBytes(bytes: Uint8Array): Signature;
|
||||
static fromHex(hex: string): Signature;
|
||||
static aggregate(signatures: Signature[]): Signature;
|
||||
static verifyMultipleSignatures(publicKeys: PublicKey[], messages: Uint8Array[], signatures: Signature[]): boolean;
|
||||
verify(publicKey: PublicKey, message: Uint8Array): boolean;
|
||||
verifyAggregate(publicKeys: PublicKey[], message: Uint8Array): boolean;
|
||||
verifyMultiple(publicKeys: PublicKey[], messages: Uint8Array[]): boolean;
|
||||
|
|
Reference in New Issue