コード例 #1
0
        /// <inheritdoc />
        public override bool TryAggregateSignatures(ReadOnlySpan <byte> signatures, Span <byte> destination,
                                                    out int bytesWritten)
        {
            // This is independent of the keys set, although other parameters (type of curve, variant, scheme, etc) are relevant.
            if (signatures.Length % SignatureLength != 0)
            {
                throw new ArgumentOutOfRangeException(nameof(signatures), signatures.Length,
                                                      $"Signature data must be a multiple of the signature length {SignatureLength}.");
            }

            if (destination.Length < SignatureLength)
            {
                bytesWritten = 0;
                return(false);
            }

            EnsureInitialised();

            var aggregateBlsSignature = default(Bls384Interop.BlsSignature);

            for (var index = 0; index < signatures.Length; index += SignatureLength)
            {
                var signatureSlice = signatures.Slice(index, SignatureLength);
                var blsSignature   = default(Bls384Interop.BlsSignature);
                int signatureBytesRead;
                unsafe
                {
                    // Using fixed pointer for input data allows us to pass a slice
                    fixed(byte *signaturePtr = signatureSlice)
                    {
                        signatureBytesRead =
                            Bls384Interop.SignatureDeserialize(ref blsSignature, signaturePtr, SignatureLength);
                    }
                }

                if (signatureBytesRead != SignatureLength)
                {
                    throw new Exception($"Error deserializing BLS signature, length: {signatureBytesRead}");
                }

                if (index == 0)
                {
                    aggregateBlsSignature = blsSignature;
                }
                else
                {
                    Bls384Interop.SignatureAdd(ref aggregateBlsSignature, ref blsSignature);
                }
            }

            unsafe
            {
                // Using fixed pointer for output data allows us to write directly to destination
                fixed(byte *destinationPtr = destination)
                {
                    bytesWritten =
                        Bls384Interop.SignatureSerialize(destinationPtr, SignatureLength, ref aggregateBlsSignature);
                }
            }

            if (bytesWritten != SignatureLength)
            {
                throw new Exception($"Error serializing BLS signature, length: {bytesWritten}");
            }

            return(true);
        }