diff --git a/src/index.ts b/src/index.ts index 422ae8f..9ce9534 100644 --- a/src/index.ts +++ b/src/index.ts @@ -48,11 +48,11 @@ export function sign(secretKey: Uint8Array, messageHash: Uint8Array): Buffer { */ export function aggregateSignatures(signatures: Uint8Array[]): Buffer { assert(signatures, "signatures is null or undefined"); - return signatures.map((signature): Signature => { - return Signature.fromCompressedBytes(toBuffer(signature)); - }).reduce((previousValue, currentValue): Signature => { - return previousValue.add(currentValue); - }).toBytesCompressed(); + return Signature.aggregate( + signatures.map((signature): Signature => { + return Signature.fromCompressedBytes(signature); + }) + ).toBytesCompressed(); } /** @@ -89,16 +89,37 @@ export function verify(publicKey: Uint8Array, messageHash: Uint8Array, signature } } +/** + * Verifies if aggregated signature is same message signed with given public keys. + * @param publicKeys + * @param messageHash + * @param signature + */ +export function verifyAggregate(publicKeys: Uint8Array[], messageHash: Uint8Array, signature: Uint8Array): boolean { + assert(publicKeys, "publicKey is null or undefined"); + assert(messageHash, "messageHash is null or undefined"); + assert(signature, "signature is null or undefined"); + try { + return Signature + .fromCompressedBytes(signature) + .verifyAggregate(publicKeys, messageHash); + } catch (e) { + return false; + } +} + /** * Verifies if signature is list of message signed with corresponding public key. * @param publicKeys * @param messageHashes * @param signature + * @param fast Check if all messages are different */ export function verifyMultiple( publicKeys: Uint8Array[], messageHashes: Uint8Array[], signature: Uint8Array, + fast = false ): boolean { assert(publicKeys, "publicKey is null or undefined"); assert(messageHashes, "messageHash is null or undefined"); @@ -113,6 +134,7 @@ export function verifyMultiple( .verifyMultiple( publicKeys.map((key) => PublicKey.fromBytes(toBuffer(key))), messageHashes.map((m) => toBuffer(m)), + fast ); } catch (e) { return false; @@ -126,5 +148,6 @@ export default { aggregateSignatures, aggregatePubkeys, verify, + verifyAggregate, verifyMultiple }; diff --git a/src/privateKey.ts b/src/privateKey.ts index 0b4134d..fb46531 100644 --- a/src/privateKey.ts +++ b/src/privateKey.ts @@ -50,7 +50,7 @@ export class PrivateKey { // } public signMessage(message: Uint8Array): Signature { - return Signature.fromValue(this.value.signHashWithDomain(message)); + return Signature.fromValue(this.value.sign(message)); } public toPublicKey(): PublicKey { diff --git a/src/publicKey.ts b/src/publicKey.ts index e1e740c..039880a 100644 --- a/src/publicKey.ts +++ b/src/publicKey.ts @@ -49,7 +49,7 @@ export class PublicKey { } public verifyMessage(signature: Signature, messageHash: Uint8Array): boolean { - return this.value.verifyHashWithDomain(signature.getValue(), messageHash); + return this.value.verify(signature.getValue(), messageHash); } public toBytesCompressed(): Buffer { diff --git a/src/signature.ts b/src/signature.ts index dd9e6e8..dbe1e01 100644 --- a/src/signature.ts +++ b/src/signature.ts @@ -11,6 +11,7 @@ export class Signature { protected constructor(value: SignatureType) { this.value = value; + assert(this.value.isValidOrder()); } public static fromCompressedBytes(value: Uint8Array): Signature { @@ -30,6 +31,15 @@ export class Signature { return new Signature(signature); } + public static aggregate(signatures: Signature[]): Signature { + const context = getContext(); + const signature = new context.Signature(); + signature.aggregate(signatures.map((sig) => sig.getValue())); + return new Signature( + signature + ); + } + public add(other: Signature): Signature { const agg = this.value.clone(); agg.add(other.value); @@ -42,14 +52,21 @@ export class Signature { return this.value; } - public verify(publicKey: PublicKey, message: Uint8Array): boolean { - return publicKey.verifyMessage(this, message); + public verifyAggregate(publicKey: Uint8Array[], message: Uint8Array): boolean { + return this.value.fastAggregateVerify( + publicKey.map((bytes) => PublicKey.fromBytes(bytes).getValue()), + message + ); } - public verifyMultiple(publicKeys: PublicKey[], messages: Uint8Array[]): boolean { - return this.value.verifyAggregatedHashWithDomain( + public verifyMultiple(publicKeys: PublicKey[], messages: Uint8Array[], fast = false): boolean { + const msgs = Buffer.concat(messages); + if(!fast && !getContext().areAllMsgDifferent(msgs)) { + return false; + } + return this.value.aggregateVerifyNoCheck( publicKeys.map((key) => key.getValue()), - messages + msgs ); }