public BlsPublicKey BlsAggregatePublicKeys(IEnumerable<BlsPublicKey> publicKeys) { // TKS: added an extension here as an example to discuss - I have been avoiding passing IEnumerable // for the performance reasons - to avoid multiple runs // and opted for passing either arrays or lists and keep it consistent // it sometimes / very rarely has an issue of having to cast list to an array // but usually we have a full control over the flow so it ends up being much better // what do you think? // TODO: [SG] yes. Change IEnumerable to IList in most places to avoid double-enumeration. Span<byte> publicKeysSpan = new Span<byte>(new byte[publicKeys.Count() * BlsPublicKey.Length]); int publicKeysSpanIndex = 0; foreach (BlsPublicKey publicKey in publicKeys) { publicKey.AsSpan().CopyTo(publicKeysSpan.Slice(publicKeysSpanIndex)); publicKeysSpanIndex += BlsPublicKey.Length; } using BLS signatureAlgorithm = SignatureAlgorithmFactory(new BLSParameters()); byte[] aggregatePublicKey = new byte[BlsPublicKey.Length]; bool success = signatureAlgorithm.TryAggregatePublicKeys(publicKeysSpan, aggregatePublicKey, out int bytesWritten); if (!success || bytesWritten != BlsPublicKey.Length) { throw new Exception("Error generating aggregate public key."); } return new BlsPublicKey(aggregatePublicKey); }
public BlsPublicKey BlsAggregatePublicKeys(IList <BlsPublicKey> publicKeys) { Span <byte> publicKeysSpan = new Span <byte>(new byte[publicKeys.Count() * BlsPublicKey.Length]); int publicKeysSpanIndex = 0; foreach (BlsPublicKey publicKey in publicKeys) { publicKey.AsSpan().CopyTo(publicKeysSpan.Slice(publicKeysSpanIndex)); publicKeysSpanIndex += BlsPublicKey.Length; } byte[] aggregatePublicKey = new byte[BlsPublicKey.Length]; bool success = _bls.TryAggregatePublicKeys(publicKeysSpan, aggregatePublicKey, out int bytesWritten); if (!success || bytesWritten != BlsPublicKey.Length) { throw new Exception("Error generating aggregate public key."); } return(new BlsPublicKey(aggregatePublicKey)); }