示例#1
0
        public override bool TryAggregatePublicKeys(ReadOnlySpan <byte> publicKeys, 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 (publicKeys.Length % PublicKeyLength != 0)
            {
                throw new ArgumentOutOfRangeException(nameof(publicKeys), publicKeys.Length, $"Public key data must be a multiple of the public key length {PublicKeyLength}.");
            }
            if (destination.Length < PublicKeyLength)
            {
                bytesWritten = 0;
                return(false);
            }

            EnsureInitialised();

            var aggregateBlsPublicKey = default(Bls384Interop.BlsPublicKey);

            for (var index = 0; index < publicKeys.Length; index += PublicKeyLength)
            {
                var publicKeySlice = publicKeys.Slice(index, PublicKeyLength);
                var blsPublicKey   = default(Bls384Interop.BlsPublicKey);
                int publicKeyBytesRead;
                unsafe
                {
                    // Using fixed pointer for input data allows us to pass a slice
                    fixed(byte *publicKeyPtr = publicKeySlice)
                    {
                        publicKeyBytesRead = Bls384Interop.PublicKeyDeserialize(ref blsPublicKey, publicKeyPtr, PublicKeyLength);
                    }
                }
                if (publicKeyBytesRead != PublicKeyLength)
                {
                    throw new Exception($"Error deserializing BLS public key, length: {publicKeyBytesRead}");
                }
                if (index == 0)
                {
                    aggregateBlsPublicKey = blsPublicKey;
                }
                else
                {
                    Bls384Interop.PublicKeyAdd(ref aggregateBlsPublicKey, ref blsPublicKey);
                }
            }

            unsafe
            {
                // Using fixed pointer for output data allows us to write directly to destination
                fixed(byte *destinationPtr = destination)
                {
                    bytesWritten = Bls384Interop.PublicKeySerialize(destinationPtr, PublicKeyLength, ref aggregateBlsPublicKey);
                }
            }
            if (bytesWritten != PublicKeyLength)
            {
                throw new Exception($"Error serializing BLS public key, length: {bytesWritten}");
            }
            return(true);
        }
示例#2
0
        private void EnsurePublicKey()
        {
            if (_publicKey == null)
            {
                if (_privateKey != null)
                {
                    EnsureInitialised();

                    // Standard values are big endian encoding (are using the Herumi deserialize / serialize)

                    var blsSecretKey = default(Bls384Interop.BlsSecretKey);
                    int bytesRead;
                    unsafe
                    {
                        fixed(byte *ptr = _privateKey)
                        {
                            bytesRead = Bls384Interop.SecretKeyDeserialize(ref blsSecretKey, ptr, _privateKey.Length);
                        }
                    }
                    if (bytesRead != _privateKey.Length)
                    {
                        throw new Exception($"Error deserializing BLS private key, length: {bytesRead}");
                    }

                    var blsPublicKey = default(Bls384Interop.BlsPublicKey);
                    Bls384Interop.GetPublicKey(ref blsPublicKey, ref blsSecretKey);

                    var buffer = new Span <byte>(new byte[PublicKeyLength]);
                    int bytesWritten;
                    unsafe
                    {
                        fixed(byte *ptr = buffer)
                        {
                            bytesWritten = Bls384Interop.PublicKeySerialize(ptr, buffer.Length, ref blsPublicKey);
                        }
                    }

                    if (bytesWritten != buffer.Length)
                    {
                        throw new Exception($"Error serializing BLS public key, length: {bytesWritten}");
                    }
                    _publicKey = buffer.ToArray();
                }
            }
        }