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());
|
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 {
|
verify(publicKey: PublicKey, message: Uint8Array): boolean {
|
||||||
// Individual infinity signatures are NOT okay. Aggregated signatures MAY be infinity
|
// Individual infinity signatures are NOT okay. Aggregated signatures MAY be infinity
|
||||||
if (this.affine.value.is_inf()) {
|
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
|
* Computes a public key from a secret key
|
||||||
*/
|
*/
|
||||||
|
@ -121,6 +151,7 @@ export function functionalInterfaceFactory({
|
||||||
verify,
|
verify,
|
||||||
verifyAggregate,
|
verifyAggregate,
|
||||||
verifyMultiple,
|
verifyMultiple,
|
||||||
|
verifyMultipleSignatures,
|
||||||
secretKeyToPublicKey,
|
secretKeyToPublicKey,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {SIGNATURE_LENGTH} from "../constants";
|
import {SIGNATURE_LENGTH} from "../constants";
|
||||||
import {SignatureType} from "bls-eth-wasm";
|
import {SignatureType, multiVerify} from "bls-eth-wasm";
|
||||||
import {getContext} from "./context";
|
import {getContext} from "./context";
|
||||||
import {PublicKey} from "./publicKey";
|
import {PublicKey} from "./publicKey";
|
||||||
import {bytesToHex, hexToBytes, isZeroUint8Array} from "../helpers";
|
import {bytesToHex, hexToBytes, isZeroUint8Array} from "../helpers";
|
||||||
|
@ -45,6 +45,14 @@ export class Signature implements ISignature {
|
||||||
return new Signature(signature);
|
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 {
|
verify(publicKey: PublicKey, message: Uint8Array): boolean {
|
||||||
return publicKey.value.verify(this.value, message);
|
return publicKey.value.verify(this.value, message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ export interface IBls {
|
||||||
fromBytes(bytes: Uint8Array): Signature;
|
fromBytes(bytes: Uint8Array): Signature;
|
||||||
fromHex(hex: string): Signature;
|
fromHex(hex: string): Signature;
|
||||||
aggregate(signatures: Signature[]): Signature;
|
aggregate(signatures: Signature[]): Signature;
|
||||||
|
verifyMultipleSignatures(publicKeys: PublicKey[], messages: Uint8Array[], signatures: Signature[]): boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
sign(secretKey: Uint8Array, message: Uint8Array): Uint8Array;
|
sign(secretKey: Uint8Array, message: Uint8Array): Uint8Array;
|
||||||
|
@ -21,6 +22,7 @@ export interface IBls {
|
||||||
verify(publicKey: Uint8Array, message: Uint8Array, signature: Uint8Array): boolean;
|
verify(publicKey: Uint8Array, message: Uint8Array, signature: Uint8Array): boolean;
|
||||||
verifyAggregate(publicKeys: Uint8Array[], message: Uint8Array, signature: Uint8Array): boolean;
|
verifyAggregate(publicKeys: Uint8Array[], message: Uint8Array, signature: Uint8Array): boolean;
|
||||||
verifyMultiple(publicKeys: Uint8Array[], messages: Uint8Array[], signature: Uint8Array): boolean;
|
verifyMultiple(publicKeys: Uint8Array[], messages: Uint8Array[], signature: Uint8Array): boolean;
|
||||||
|
verifyMultipleSignatures(publicKeys: Uint8Array[], messages: Uint8Array[], signatures: Uint8Array[]): boolean;
|
||||||
secretKeyToPublicKey(secretKey: Uint8Array): Uint8Array;
|
secretKeyToPublicKey(secretKey: Uint8Array): Uint8Array;
|
||||||
|
|
||||||
init(): Promise<void>;
|
init(): Promise<void>;
|
||||||
|
@ -49,6 +51,7 @@ export declare class Signature {
|
||||||
static fromBytes(bytes: Uint8Array): Signature;
|
static fromBytes(bytes: Uint8Array): Signature;
|
||||||
static fromHex(hex: string): Signature;
|
static fromHex(hex: string): Signature;
|
||||||
static aggregate(signatures: Signature[]): Signature;
|
static aggregate(signatures: Signature[]): Signature;
|
||||||
|
static verifyMultipleSignatures(publicKeys: PublicKey[], messages: Uint8Array[], signatures: Signature[]): boolean;
|
||||||
verify(publicKey: PublicKey, message: Uint8Array): boolean;
|
verify(publicKey: PublicKey, message: Uint8Array): boolean;
|
||||||
verifyAggregate(publicKeys: PublicKey[], message: Uint8Array): boolean;
|
verifyAggregate(publicKeys: PublicKey[], message: Uint8Array): boolean;
|
||||||
verifyMultiple(publicKeys: PublicKey[], messages: Uint8Array[]): boolean;
|
verifyMultiple(publicKeys: PublicKey[], messages: Uint8Array[]): boolean;
|
||||||
|
|
Reference in New Issue