Ejemplo n.º 1
0
        public IList <BlsPublicKey> GetPublicKeys()
        {
            if (_publicKeyToBls.Count == 0)
            {
                QuickStartParameters _quickStartParameters = _quickStartParameterOptions.CurrentValue;

                ulong endIndex = _quickStartParameters.ValidatorStartIndex + _quickStartParameters.NumberOfValidators;
                for (ulong validatorIndex = _quickStartParameters.ValidatorStartIndex;
                     validatorIndex < endIndex;
                     validatorIndex++)
                {
                    byte[] privateKey = GeneratePrivateKey(validatorIndex);

                    BLSParameters blsParameters = new BLSParameters()
                    {
                        PrivateKey = privateKey
                    };
                    BLS    bls            = BLS.Create(blsParameters);
                    byte[] publicKeyBytes = new byte[BlsPublicKey.Length];
                    bls.TryExportBlsPublicKey(publicKeyBytes, out int publicKeyBytesWritten);
                    BlsPublicKey publicKey = new BlsPublicKey(publicKeyBytes);

                    // Cache the BLS class, for easy signing
                    _publicKeyToBls[publicKey] = bls;
                }
            }

            return(_publicKeyToBls.Keys.ToList());
        }
Ejemplo n.º 2
0
        public void BlsRoundtripSignAndVerify()
        {
            // Arrange
            var privateKey  = HexMate.Convert.FromHexString(PrivateKeys[1]);
            var messageHash = MessageHashes[0];
            var domain      = Domains[0];

            Console.WriteLine("Input:");
            Console.WriteLine("Private Key: [{0}] {1}", privateKey.Length, HexMate.Convert.ToHexString(privateKey));
            Console.WriteLine("Domain: [{0}] {1}", domain.Length, HexMate.Convert.ToHexString(domain));
            Console.WriteLine("MessageHash: [{0}] {1}", messageHash.Length, HexMate.Convert.ToHexString(messageHash));

            // Act
            var parameters = new BLSParameters()
            {
                PrivateKey = privateKey
            };

            using var bls = new BLSHerumi(parameters);

            var publicKey = new byte[48];

            _ = bls.TryExportBLSPublicKey(publicKey, out var _);

            Console.WriteLine("Public Key: [{0}] {1}", publicKey.Length, HexMate.Convert.ToHexString(publicKey));

            var initialX = new byte[96];

            _ = bls.TryCombineHashAndDomain(messageHash, domain, initialX, out var _);

            Console.WriteLine("InitialX: [{0}] {1}", initialX.Length, HexMate.Convert.ToHexString(initialX));

            var signature        = new byte[96];
            var signatureSuccess = bls.TrySignHash(initialX, signature.AsSpan(), out var bytesWritten);

            Console.WriteLine("Signature: {0} [{1}] {2}", signatureSuccess, bytesWritten, HexMate.Convert.ToHexString(signature));

            //var expectedSignature = HexMate.Convert.FromHexString("b9d1bf921b3dd048bdce38c2ceac2a2a8093c864881f2415f22b198de935ffa791707855c1656dc21a7af2d502bb46590151d645f062634c3b2cb79c4ed1c4a4b8b3f19f0f5c76965c651553e83d153ff95353735156eff77692f7a62ae653fb");
            //signature.ShouldBe(expectedSignature);

            var verifySuccess = bls.VerifyHash(initialX, signature);

            Console.WriteLine("Verify1: {0}", verifySuccess);

            var parameters2 = new BLSParameters()
            {
                PublicKey = publicKey
            };

            using var bls2 = new BLSHerumi(parameters);

            var verifySuccess2 = bls2.VerifyHash(initialX, signature);

            Console.WriteLine("Verify2: {0}", verifySuccess2);

            verifySuccess2.ShouldBeTrue();
        }
        public bool BlsVerify(BlsPublicKey publicKey, Root signingRoot, BlsSignature signature)
        {
            BLSParameters blsParameters = new BLSParameters()
            {
                PublicKey = publicKey.AsSpan().ToArray()
            };

            using BLS signatureAlgorithm = SignatureAlgorithmFactory(blsParameters);
            return(signatureAlgorithm.VerifyHash(signingRoot.AsSpan(), signature.AsSpan()));
        }
Ejemplo n.º 4
0
        public bool BlsVerify(BlsPublicKey publicKey, Hash32 messageHash, BlsSignature signature, Domain domain)
        {
            var blsParameters = new BLSParameters()
            {
                PublicKey = publicKey.AsSpan().ToArray()
            };

            using var signatureAlgorithm = SignatureAlgorithmFactory(blsParameters);
            return(signatureAlgorithm.VerifyHash(messageHash.AsSpan(), signature.AsSpan(), domain.AsSpan()));
        }
Ejemplo n.º 5
0
        public CryptographyService(ChainConstants chainConstants,
                                   IOptionsMonitor <MiscellaneousParameters> miscellaneousParameterOptions,
                                   IOptionsMonitor <TimeParameters> timeParameterOptions,
                                   IOptionsMonitor <StateListLengths> stateListLengthOptions,
                                   IOptionsMonitor <MaxOperationsPerBlock> maxOperationsPerBlockOptions)
        {
            _chainConstants = chainConstants;
            _miscellaneousParameterOptions = miscellaneousParameterOptions;
            _timeParameterOptions          = timeParameterOptions;
            _stateListLengthOptions        = stateListLengthOptions;
            _maxOperationsPerBlockOptions  = maxOperationsPerBlockOptions;

            MiscellaneousParameters miscellaneousParameters = miscellaneousParameterOptions.CurrentValue;
            TimeParameters          timeParameters          = timeParameterOptions.CurrentValue;
            StateListLengths        stateListLengths        = stateListLengthOptions.CurrentValue;
            MaxOperationsPerBlock   maxOperationsPerBlock   = maxOperationsPerBlockOptions.CurrentValue;

            BLSParameters blsParameters = new BLSParameters();

            _bls = BLS.Create(blsParameters);

            Nethermind.Ssz.Ssz.Init(
                chainConstants.DepositContractTreeDepth,
                chainConstants.JustificationBitsLength,
                miscellaneousParameters.MaximumValidatorsPerCommittee,
                timeParameters.SlotsPerEpoch,
                timeParameters.SlotsPerEth1VotingPeriod,
                timeParameters.SlotsPerHistoricalRoot,
                stateListLengths.EpochsPerHistoricalVector,
                stateListLengths.EpochsPerSlashingsVector,
                stateListLengths.HistoricalRootsLimit,
                stateListLengths.ValidatorRegistryLimit,
                maxOperationsPerBlock.MaximumProposerSlashings,
                maxOperationsPerBlock.MaximumAttesterSlashings,
                maxOperationsPerBlock.MaximumAttestations,
                maxOperationsPerBlock.MaximumDeposits,
                maxOperationsPerBlock.MaximumVoluntaryExits);

            Nethermind.Ssz.Ssz.Init(
                chainConstants.DepositContractTreeDepth,
                chainConstants.JustificationBitsLength,
                miscellaneousParameters.MaximumValidatorsPerCommittee,
                timeParameters.SlotsPerEpoch,
                timeParameters.SlotsPerEth1VotingPeriod,
                timeParameters.SlotsPerHistoricalRoot,
                stateListLengths.EpochsPerHistoricalVector,
                stateListLengths.EpochsPerSlashingsVector,
                stateListLengths.HistoricalRootsLimit,
                stateListLengths.ValidatorRegistryLimit,
                maxOperationsPerBlock.MaximumProposerSlashings,
                maxOperationsPerBlock.MaximumAttesterSlashings,
                maxOperationsPerBlock.MaximumAttestations,
                maxOperationsPerBlock.MaximumDeposits,
                maxOperationsPerBlock.MaximumVoluntaryExits);
        }
Ejemplo n.º 6
0
        public static BlsSignature BlsSign(Root messageHash, byte[] privateKey)
        {
            var parameters = new BLSParameters()
            {
                PrivateKey = privateKey
            };

            using var signingAlgorithm = SignatureAlgorithmFactory(parameters);
            var destination = new byte[96];
            var success     = signingAlgorithm.TrySignData(messageHash.AsSpan(), destination, out var bytesWritten);

            return(new BlsSignature(destination));
        }
Ejemplo n.º 7
0
        public static BlsSignature BlsSign(Hash32 messageHash, byte[] privateKey, Domain domain)
        {
            var parameters = new BLSParameters()
            {
                PrivateKey = privateKey
            };

            using var signingAlgorithm = SignatureAlgorithmFactory(parameters);
            var destination = new byte[96];
            var success     = signingAlgorithm.TrySignHash(messageHash.AsSpan(), destination, out var bytesWritten, domain.AsSpan().ToArray());

            return(new BlsSignature(destination));
        }
Ejemplo n.º 8
0
        private DepositData BuildAndSignDepositData(ulong validatorIndex, Gwei amount, SignatureDomains signatureDomains)
        {
            InitialValues initialValues = _initialValueOptions.CurrentValue;

            byte[] privateKey = GeneratePrivateKey(validatorIndex);

            // Public Key
            BLSParameters blsParameters = new BLSParameters
            {
                PrivateKey = privateKey
            };

            using BLS bls = BLS.Create(blsParameters);
            byte[] publicKeyBytes = new byte[BlsPublicKey.Length];
            bls.TryExportBlsPublicKey(publicKeyBytes, out int publicKeyBytesWritten);
            BlsPublicKey publicKey = new BlsPublicKey(publicKeyBytes);

            // Withdrawal Credentials
            Bytes32 withdrawalCredentials = _crypto.Hash(publicKey.AsSpan());

            withdrawalCredentials.Unwrap()[0] = initialValues.BlsWithdrawalPrefix;

            // Build deposit data
            DepositData depositData = new DepositData(publicKey, withdrawalCredentials, amount, BlsSignature.Zero);

            // Sign deposit data
            Domain         domain         = _beaconChainUtility.ComputeDomain(signatureDomains.Deposit);
            DepositMessage depositMessage = new DepositMessage(
                depositData.PublicKey,
                depositData.WithdrawalCredentials,
                depositData.Amount);

            Root depositMessageRoot     = _crypto.HashTreeRoot(depositMessage);
            Root depositDataSigningRoot = _beaconChainUtility.ComputeSigningRoot(depositMessageRoot, domain);

            byte[] signatureBytes = new byte[96];
            bls.TrySignData(depositDataSigningRoot.AsSpan(), signatureBytes, out int bytesWritten);

            BlsSignature depositDataSignature = new BlsSignature(signatureBytes);

            depositData.SetSignature(depositDataSignature);

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                LogDebug.QuickStartAddValidator(_logger, validatorIndex, publicKey.ToString().Substring(0, 12),
                                                null);
            }

            return(depositData);
        }
Ejemplo n.º 9
0
        public void DataSignAndVerify()
        {
            // Arrange
            var privateKey  = HexMate.Convert.FromHexString(PrivateKeys[1]);
            var messageData = MessageData[1];

            Console.WriteLine("Input:");
            Console.WriteLine("Private Key: [{0}] {1}", privateKey.Length, HexMate.Convert.ToHexString(privateKey));
            Console.WriteLine("MessageData: [{0}] {1}", messageData.Length, HexMate.Convert.ToHexString(messageData));

            // Act
            var parameters = new BLSParameters()
            {
                PrivateKey = privateKey
            };

            using var bls = new BLSHerumi(parameters);

            var publicKey = new byte[48];

            _ = bls.TryExportBlsPublicKey(publicKey, out var _);

            Console.WriteLine("Public Key: [{0}] {1}", publicKey.Length, HexMate.Convert.ToHexString(publicKey));

            var signature        = new byte[96];
            var signatureSuccess = bls.TrySignData(messageData, signature.AsSpan(), out var bytesWritten);

            Console.WriteLine("Signature: {0} [{1}] {2}", signatureSuccess, bytesWritten, HexMate.Convert.ToHexString(signature));

            var verifySuccess = bls.VerifyData(messageData, signature);

            Console.WriteLine("Verify1: {0}", verifySuccess);

            var parameters2 = new BLSParameters()
            {
                PublicKey = publicKey
            };

            using var bls2 = new BLSHerumi(parameters);

            var verifySuccess2 = bls2.VerifyData(messageData, signature);

            Console.WriteLine("Verify2: {0}", verifySuccess2);

            verifySuccess2.ShouldBeTrue();
        }
Ejemplo n.º 10
0
        public void TestPrivateKeyToPublic()
        {
            var privateKeyBytes = Bytes.FromHexString("47b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665138");

            Console.WriteLine("Serialized private key: {0}", privateKeyBytes.ToHexString());

            //BlsProxy.GetPublicKey(privateKeyBytes, out var publicKeySpan);
            var parameters = new BLSParameters()
            {
                PrivateKey = privateKeyBytes
            };

            using var bls = new BLSHerumi(parameters);
            var result  = new byte[48];
            var success = bls.TryExportBlsPublicKey(result.AsSpan(), out var bytesWritten);

            //var publicKeyBytes = publicKeySpan.ToArray();
            var publicKeyBytes = result;

            Assert.AreEqual("b301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", publicKeyBytes.ToHexString());
        }
Ejemplo n.º 11
0
        private static void EnsureKeys(TimeParameters timeParameters)
        {
            var keysRequired = (int)(ulong)timeParameters.SlotsPerEpoch * 16;

            if (_testKeys.Count == keysRequired)
            {
                return;
            }

            _testKeys.Clear();
            _privateKeys.Clear();
            _publicKeys.Clear();
            // Private key is ~255 bits (32 bytes) long
            for (var keyNumber = 0; keyNumber < keysRequired; keyNumber++)
            {
                var privateKeySpan = new Span <byte>(new byte[32]);
                // Key is big endian number, so write Int32 to last 4 bytes.
                BitConverter.TryWriteBytes(privateKeySpan.Slice(28), keyNumber + 1);
                if (BitConverter.IsLittleEndian)
                {
                    // And reverse if necessary
                    privateKeySpan.Slice(28).Reverse();
                }
                var privateKey = privateKeySpan.ToArray();

                var blsParameters = new BLSParameters()
                {
                    PrivateKey = privateKey
                };
                using var bls = BLS.Create(blsParameters);
                var publicKeyBytes = new byte[BlsPublicKey.Length];
                bls.TryExportBLSPublicKey(publicKeyBytes, out var bytesWritten);
                var publicKey = new BlsPublicKey(publicKeyBytes);

                _privateKeys.Add(privateKey);
                _publicKeys.Add(publicKey);
                _testKeys[publicKey] = privateKey;
            }
        }
Ejemplo n.º 12
0
        public void Verify(string testName, byte[] publicKey, byte[] messageData, byte[] signature, bool expected)
        {
            // Arrange
            var parameters = new BLSParameters()
            {
                PublicKey = publicKey
            };

            Console.WriteLine("Input:");
            Console.WriteLine("Public Key: [{0}] {1}", publicKey.Length, HexMate.Convert.ToHexString(publicKey));
            Console.WriteLine("MessageHash: [{0}] {1}", messageData.Length, HexMate.Convert.ToHexString(messageData));
            Console.WriteLine("Signature: [{0}] {1}", signature.Length, HexMate.Convert.ToHexString(signature));

            // Act
            using var bls = new BLSHerumi(parameters);
            var success = bls.VerifyData(messageData, signature);

            Console.WriteLine("Output: Success {0}", success);

            // Assert
            success.ShouldBe(expected);
        }
Ejemplo n.º 13
0
        public void Case03PrivateToPublicKey(byte[] privateKey, byte[] expected)
        {
            // Arrange
            var parameters = new BLSParameters()
            {
                PrivateKey = privateKey
            };

            Console.WriteLine("Input:");
            Console.WriteLine("Private Key: [{0}] {1}", privateKey.Length, HexMate.Convert.ToHexString(privateKey));

            // Act
            using var bls = new BLSHerumi(parameters);
            var result  = new byte[48];
            var success = bls.TryExportBlsPublicKey(result.AsSpan(), out var bytesWritten);

            Console.WriteLine("Output:");
            Console.WriteLine("Public Key: [{0}] {1}", result.Length, HexMate.Convert.ToHexString(result));

            // Assert
            result.ShouldBe(expected);
        }
Ejemplo n.º 14
0
        private BlsSignature GetEpochSignature(IServiceProvider testServiceProvider, byte[] privateKey, ForkVersion forkVersion, Slot slot)
        {
            SignatureDomains   signatureDomains   = testServiceProvider.GetService <IOptions <SignatureDomains> >().Value;
            BeaconChainUtility beaconChainUtility = testServiceProvider.GetService <BeaconChainUtility>();
            var domain = beaconChainUtility.ComputeDomain(signatureDomains.Randao, forkVersion);

            var epoch = beaconChainUtility.ComputeEpochAtSlot(slot);

            var epochRoot = epoch.HashTreeRoot();

            BLSParameters parameters = new BLSParameters()
            {
                PrivateKey = privateKey
            };
            BLS bls         = BLS.Create(parameters);
            var destination = new Span <byte>(new byte[96]);

            bls.TrySignHash(epochRoot.AsSpan(), destination, out var bytesWritten, domain.AsSpan());

            var signature = new BlsSignature(destination.ToArray());

            return(signature);
        }
Ejemplo n.º 15
0
        public void Case05VerifyMessages(byte[] publicKey, byte[] messageHash, byte[] domain, byte[] signature, bool expected)
        {
            // Arrange
            var parameters = new BLSParameters()
            {
                PublicKey = publicKey
            };

            Console.WriteLine("Input:");
            Console.WriteLine("Public Key: [{0}] {1}", publicKey.Length, HexMate.Convert.ToHexString(publicKey));
            Console.WriteLine("MessageHash: [{0}] {1}", messageHash.Length, HexMate.Convert.ToHexString(messageHash));
            Console.WriteLine("Domain: [{0}] {1}", domain.Length, HexMate.Convert.ToHexString(domain));
            Console.WriteLine("Signature: [{0}] {1}", signature.Length, HexMate.Convert.ToHexString(signature));

            // Act
            using var bls = new BLSHerumi(parameters);
            var success = bls.VerifyHash(messageHash, signature, domain);

            Console.WriteLine("Output: Success {0}", success);

            // Assert
            success.ShouldBe(expected);
        }
Ejemplo n.º 16
0
        public void Sign(string testName, byte[] privateKey, byte[] messageData, byte[] expected)
        {
            // Arrange
            var parameters = new BLSParameters()
            {
                PrivateKey = privateKey
            };

            Console.WriteLine("Input:");
            Console.WriteLine("MessageData: [{0}] {1}", messageData.Length, HexMate.Convert.ToHexString(messageData));
            Console.WriteLine("Private Key: [{0}] {1}", privateKey.Length, HexMate.Convert.ToHexString(privateKey));

            // Act
            using var bls = new BLSHerumi(parameters);
            var result = new byte[96];
            //var success = bls.TrySignData(privateKey, messageData, result.AsSpan(), out var bytesWritten);
            var success = bls.TrySignData(messageData, result.AsSpan(), out var bytesWritten);

            Console.WriteLine("Output:");
            Console.WriteLine("Signature: {0} [{1}] {2}", success, bytesWritten, HexMate.Convert.ToHexString(result));

            // Assert
            result.ShouldBe(expected);
        }
Ejemplo n.º 17
0
        public void Case04SignMessages(byte[] privateKey, byte[] messageHash, byte[] domain, byte[] expected)
        {
            // Arrange
            var parameters = new BLSParameters()
            {
                PrivateKey = privateKey
            };

            Console.WriteLine("Input:");
            Console.WriteLine("Domain: [{0}] {1}", domain.Length, HexMate.Convert.ToHexString(domain));
            Console.WriteLine("MessageHash: [{0}] {1}", messageHash.Length, HexMate.Convert.ToHexString(messageHash));
            Console.WriteLine("Private Key: [{0}] {1}", privateKey.Length, HexMate.Convert.ToHexString(privateKey));

            // Act
            using var bls = new BLSHerumi(parameters);
            var result  = new byte[96];
            var success = bls.TrySignHash(messageHash, result.AsSpan(), out var bytesWritten, domain);

            Console.WriteLine("Output:");
            Console.WriteLine("Signature: {0} [{1}] {2}", success, bytesWritten, HexMate.Convert.ToHexString(result));

            // Assert
            result.ShouldBe(expected);
        }
        public Task <Eth1GenesisData> GetEth1GenesisDataAsync(CancellationToken cancellationToken)
        {
            QuickStartParameters quickStartParameters = _quickStartParameterOptions.CurrentValue;

            if (_logger.IsWarn())
            {
                Log.MockedQuickStart(_logger, quickStartParameters.GenesisTime, quickStartParameters.ValidatorCount,
                                     null);
            }

            GweiValues       gweiValues       = _gweiValueOptions.CurrentValue;
            InitialValues    initialValues    = _initialValueOptions.CurrentValue;
            TimeParameters   timeParameters   = _timeParameterOptions.CurrentValue;
            SignatureDomains signatureDomains = _signatureDomainOptions.CurrentValue;

            // Fixed amount
            Gwei amount = gweiValues.MaximumEffectiveBalance;

            // Build deposits
            List <DepositData> depositDataList = new List <DepositData>();
            List <Deposit>     deposits        = new List <Deposit>();

            for (ulong validatorIndex = 0uL; validatorIndex < quickStartParameters.ValidatorCount; validatorIndex++)
            {
                byte[] privateKey = GeneratePrivateKey(validatorIndex);

                // Public Key
                BLSParameters blsParameters = new BLSParameters()
                {
                    PrivateKey = privateKey
                };
                using BLS bls = BLS.Create(blsParameters);
                byte[] publicKeyBytes = new byte[BlsPublicKey.Length];
                bls.TryExportBlsPublicKey(publicKeyBytes, out int publicKeyBytesWritten);
                BlsPublicKey publicKey = new BlsPublicKey(publicKeyBytes);

                // Withdrawal Credentials
                byte[] withdrawalCredentialBytes = _cryptographyService.Hash(publicKey.AsSpan()).AsSpan().ToArray();
                withdrawalCredentialBytes[0] = initialValues.BlsWithdrawalPrefix;
                Bytes32 withdrawalCredentials = new Bytes32(withdrawalCredentialBytes);

                // Build deposit data
                DepositData depositData = new DepositData(publicKey, withdrawalCredentials, amount, BlsSignature.Zero);

                // Sign deposit data
                Domain         domain         = _beaconChainUtility.ComputeDomain(signatureDomains.Deposit);
                DepositMessage depositMessage = new DepositMessage(depositData.PublicKey,
                                                                   depositData.WithdrawalCredentials, depositData.Amount);
                Root   depositMessageRoot     = _cryptographyService.HashTreeRoot(depositMessage);
                Root   depositDataSigningRoot = _beaconChainUtility.ComputeSigningRoot(depositMessageRoot, domain);
                byte[] destination            = new byte[96];
                bls.TrySignData(depositDataSigningRoot.AsSpan(), destination, out int bytesWritten);
                BlsSignature depositDataSignature = new BlsSignature(destination);
                depositData.SetSignature(depositDataSignature);

                // Deposit

                // TODO: This seems a very inefficient way (copied from tests) as it recalculates the merkle tree each time
                // (you only need to add one node)

                // TODO: Add some tests around quick start, then improve

                int index = depositDataList.Count;
                depositDataList.Add(depositData);
                //int depositDataLength = (ulong) 1 << _chainConstants.DepositContractTreeDepth;
                Root root = _cryptographyService.HashTreeRoot(depositDataList);
                IEnumerable <Bytes32> allLeaves = depositDataList.Select(x =>
                                                                         new Bytes32(_cryptographyService.HashTreeRoot((DepositData)x).AsSpan()));
                IList <IList <Bytes32> > tree = CalculateMerkleTreeFromLeaves(allLeaves);


                IList <Bytes32> merkleProof = GetMerkleProof(tree, index, 32);
                List <Bytes32>  proof       = new List <Bytes32>(merkleProof);

                byte[] indexBytes = new byte[32];
                BinaryPrimitives.WriteInt32LittleEndian(indexBytes, index + 1);
                Bytes32 indexHash = new Bytes32(indexBytes);
                proof.Add(indexHash);
                Bytes32 leaf = new Bytes32(_cryptographyService.HashTreeRoot(depositData).AsSpan());
                _beaconChainUtility.IsValidMerkleBranch(leaf, proof, _chainConstants.DepositContractTreeDepth + 1,
                                                        (ulong)index, root);
                Deposit deposit = new Deposit(proof, depositData);

                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    LogDebug.QuickStartAddValidator(_logger, validatorIndex, publicKey.ToString().Substring(0, 12),
                                                    null);
                }

                deposits.Add(deposit);
            }

            ulong eth1Timestamp = quickStartParameters.Eth1Timestamp;

            if (eth1Timestamp == 0)
            {
                eth1Timestamp = quickStartParameters.GenesisTime - (ulong)(1.5 * timeParameters.MinimumGenesisDelay);
            }
            else
            {
                ulong minimumEth1TimestampInclusive =
                    quickStartParameters.GenesisTime - 2 * timeParameters.MinimumGenesisDelay;
                ulong maximumEth1TimestampInclusive =
                    quickStartParameters.GenesisTime - timeParameters.MinimumGenesisDelay - 1;
                if (eth1Timestamp < minimumEth1TimestampInclusive)
                {
                    if (_logger.IsEnabled(LogLevel.Warning))
                    {
                        Log.QuickStartEth1TimestampTooLow(_logger, eth1Timestamp, quickStartParameters.GenesisTime,
                                                          minimumEth1TimestampInclusive, null);
                    }
                    eth1Timestamp = minimumEth1TimestampInclusive;
                }
                else if (eth1Timestamp > maximumEth1TimestampInclusive)
                {
                    if (_logger.IsEnabled(LogLevel.Warning))
                    {
                        Log.QuickStartEth1TimestampTooHigh(_logger, eth1Timestamp, quickStartParameters.GenesisTime,
                                                           maximumEth1TimestampInclusive, null);
                    }
                    eth1Timestamp = maximumEth1TimestampInclusive;
                }
            }

            var eth1GenesisData = new Eth1GenesisData(quickStartParameters.Eth1BlockHash, eth1Timestamp,
                                                      deposits);

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                LogDebug.QuickStartGenesisDataCreated(_logger, eth1GenesisData.BlockHash, eth1GenesisData.Timestamp,
                                                      eth1GenesisData.Deposits.Count, null);
            }

            return(Task.FromResult(eth1GenesisData));
        }
Ejemplo n.º 19
0
        public void BlsRoundtripAggregatePublicKeyVerifySharedHash()
        {
            // Arrange
            var privateKey1       = HexMate.Convert.FromHexString(PrivateKeys[1]);
            var privateKey2       = HexMate.Convert.FromHexString(PrivateKeys[2]);
            var sharedMessageHash = MessageHashes[1];
            var domain1           = Domains[1];

            Console.WriteLine("Input:");
            Console.WriteLine("Private Key 1: [{0}] {1}", privateKey1.Length, HexMate.Convert.ToHexString(privateKey1));
            Console.WriteLine("Private Key 2: [{0}] {1}", privateKey2.Length, HexMate.Convert.ToHexString(privateKey2));
            Console.WriteLine("MessageHash 1: [{0}] {1}", sharedMessageHash.Length, HexMate.Convert.ToHexString(sharedMessageHash));
            Console.WriteLine("Domain: [{0}] {1}", domain1.Length, HexMate.Convert.ToHexString(domain1));

            // Sign 1
            using var bls1 = new BLSHerumi(new BLSParameters()
            {
                PrivateKey = privateKey1
            });
            var signature1 = new byte[96];

            _ = bls1.TrySignHash(sharedMessageHash, signature1.AsSpan(), out var _, domain1);
            Console.WriteLine("Signature 1: [{0}] {1}", signature1.Length, HexMate.Convert.ToHexString(signature1));
            var publicKey1 = new byte[48];

            _ = bls1.TryExportBlsPublicKey(publicKey1, out var _);
            Console.WriteLine("Public Key 1: [{0}] {1}", publicKey1.Length, HexMate.Convert.ToHexString(publicKey1));

            // Sign 2
            using var bls2 = new BLSHerumi(new BLSParameters()
            {
                PrivateKey = privateKey2
            });
            var signature2 = new byte[96];

            _ = bls2.TrySignHash(sharedMessageHash, signature2.AsSpan(), out var _, domain1);
            Console.WriteLine("Signature 2: [{0}] {1}", signature2.Length, HexMate.Convert.ToHexString(signature2));
            var publicKey2 = new byte[48];

            _ = bls2.TryExportBlsPublicKey(publicKey2, out var _);
            Console.WriteLine("Public Key 2: [{0}] {1}", publicKey2.Length, HexMate.Convert.ToHexString(publicKey2));

            // Aggregate public keys
            var publicKeys = new Span <byte>(new byte[48 * 2]);

            publicKey1.CopyTo(publicKeys);
            publicKey2.CopyTo(publicKeys.Slice(48));
            using var blsAggregateKeys = new BLSHerumi(new BLSParameters());
            var aggregatePublicKey = new byte[48];

            blsAggregateKeys.TryAggregatePublicKeys(publicKeys, aggregatePublicKey, out var _);
            Console.WriteLine("Aggregate Public Key: [{0}] {1}", aggregatePublicKey.Length, HexMate.Convert.ToHexString(aggregatePublicKey));

            // Aggregate signatures
            var signatures = new Span <byte>(new byte[96 * 2]);

            signature1.CopyTo(signatures);
            signature2.CopyTo(signatures.Slice(96));
            using var blsAggregate = new BLSHerumi(new BLSParameters());
            var aggregateSignature = new byte[96];

            blsAggregate.TryAggregateSignatures(signatures, aggregateSignature, out var _);
            Console.WriteLine("Aggregate Signature: [{0}] {1}", aggregateSignature.Length, HexMate.Convert.ToHexString(aggregateSignature));

            // Verify aggregates
            // i.e. the combined aggregatePublicKey / aggregateSignature are a valid pair
            var aggregatePublicKeyParameters = new BLSParameters()
            {
                PublicKey = aggregatePublicKey
            };

            using var blsVerify = new BLSHerumi(aggregatePublicKeyParameters);
            var verifySuccess = blsVerify.VerifyHash(sharedMessageHash, aggregateSignature, domain1);

            Console.WriteLine("Verify: {0}", verifySuccess);

            verifySuccess.ShouldBeTrue();
        }
Ejemplo n.º 20
0
        public void QuickStartGenesis()
        {
            QuickStartParameters quickStartParameters = _quickStartParameterOptions.CurrentValue;

            if (_logger.IsWarn())
            {
                Log.MockedQuickStart(_logger, quickStartParameters.GenesisTime, quickStartParameters.ValidatorCount, null);
            }

            GweiValues       gweiValues       = _gweiValueOptions.CurrentValue;
            InitialValues    initialValues    = _initialValueOptions.CurrentValue;
            SignatureDomains signatureDomains = _signatureDomainOptions.CurrentValue;

            // Fixed amount
            Gwei amount = gweiValues.MaximumEffectiveBalance;

            // Build deposits
            List <DepositData> depositDataList = new List <DepositData>();
            List <Deposit>     deposits        = new List <Deposit>();

            for (ulong validatorIndex = 0uL; validatorIndex < quickStartParameters.ValidatorCount; validatorIndex++)
            {
                byte[] privateKey = GeneratePrivateKey(validatorIndex);

                // Public Key
                BLSParameters blsParameters = new BLSParameters()
                {
                    PrivateKey = privateKey
                };
                using BLS bls = BLS.Create(blsParameters);
                byte[] publicKeyBytes = new byte[BlsPublicKey.Length];
                bls.TryExportBLSPublicKey(publicKeyBytes, out int publicKeyBytesWritten);
                BlsPublicKey publicKey = new BlsPublicKey(publicKeyBytes);

                // Withdrawal Credentials
                byte[] withdrawalCredentialBytes = _cryptographyService.Hash(publicKey.AsSpan()).AsSpan().ToArray();
                withdrawalCredentialBytes[0] = initialValues.BlsWithdrawalPrefix;
                Hash32 withdrawalCredentials = new Hash32(withdrawalCredentialBytes);

                // Build deposit data
                DepositData depositData = new DepositData(publicKey, withdrawalCredentials, amount);

                // Sign deposit data
                Hash32 depositDataSigningRoot = _cryptographyService.SigningRoot(depositData);
                Domain domain      = _beaconChainUtility.ComputeDomain(signatureDomains.Deposit);
                byte[] destination = new byte[96];
                bls.TrySignHash(depositDataSigningRoot.AsSpan(), destination, out int bytesWritten, domain.AsSpan());
                BlsSignature depositDataSignature = new BlsSignature(destination);
                depositData.SetSignature(depositDataSignature);

                // Deposit

                // TODO: This seems a very inefficient way (copied from tests) as it recalculates the merkle tree each time
                // (you only need to add one node)

                // TODO: Add some tests around quick start, then improve

                int index = depositDataList.Count;
                depositDataList.Add(depositData);
                //int depositDataLength = (ulong) 1 << _chainConstants.DepositContractTreeDepth;
                Hash32 root = _cryptographyService.HashTreeRoot(depositDataList);
                IEnumerable <Hash32>    allLeaves = depositDataList.Select(x => _cryptographyService.HashTreeRoot(x));
                IList <IList <Hash32> > tree      = CalculateMerkleTreeFromLeaves(allLeaves);


                IList <Hash32> merkleProof = GetMerkleProof(tree, index, 32);
                List <Hash32>  proof       = new List <Hash32>(merkleProof);
                Span <byte>    indexBytes  = new Span <byte>(new byte[32]);
                BitConverter.TryWriteBytes(indexBytes, (ulong)index + 1);
                if (!BitConverter.IsLittleEndian)
                {
                    indexBytes.Slice(0, 8).Reverse();
                }

                Hash32 indexHash = new Hash32(indexBytes);
                proof.Add(indexHash);
                Hash32 leaf = _cryptographyService.HashTreeRoot(depositData);
                _beaconChainUtility.IsValidMerkleBranch(leaf, proof, _chainConstants.DepositContractTreeDepth + 1, (ulong)index, root);
                Deposit deposit = new Deposit(proof, depositData);

                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    LogDebug.QuickStartAddValidator(_logger, validatorIndex, publicKey.ToString().Substring(0, 12),
                                                    null);
                }

                deposits.Add(deposit);
            }

            BeaconState genesisState = _beaconChain.InitializeBeaconStateFromEth1(quickStartParameters.Eth1BlockHash, quickStartParameters.Eth1Timestamp, deposits);

            // We use the state directly, and don't test IsValid
            genesisState.SetGenesisTime(quickStartParameters.GenesisTime);
            IStore store = _forkChoice.GetGenesisStore(genesisState);

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                LogDebug.QuickStartStoreCreated(_logger, store.GenesisTime, null);
            }
        }
Ejemplo n.º 21
0
        public void QuickStartGenesis()
        {
            var quickStartParameters = _quickStartParameterOptions.CurrentValue;

            _logger.LogWarning(0, "Mocked quick start with genesis time {GenesisTime} and {ValidatorCount} validators.",
                               quickStartParameters.GenesisTime, quickStartParameters.ValidatorCount);

            var miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue;
            var gweiValues            = _gweiValueOptions.CurrentValue;
            var initialValues         = _initialValueOptions.CurrentValue;
            var timeParameters        = _timeParameterOptions.CurrentValue;
            var stateListLengths      = _stateListLengthOptions.CurrentValue;
            var maxOperationsPerBlock = _maxOperationsPerBlockOptions.CurrentValue;
            var signatureDomains      = _signatureDomainOptions.CurrentValue;

            // Fixed amount
            var amount = gweiValues.MaximumEffectiveBalance;

            // Build deposits
            var depositDataList = new List <DepositData>();
            var deposits        = new List <Deposit>();

            for (var validatorIndex = 0uL; validatorIndex < quickStartParameters.ValidatorCount; validatorIndex++)
            {
                var privateKey = GeneratePrivateKey(validatorIndex);

                // Public Key
                var blsParameters = new BLSParameters()
                {
                    PrivateKey = privateKey
                };
                using var bls = BLS.Create(blsParameters);
                var publicKeyBytes = new Span <byte>(new byte[BlsPublicKey.Length]);
                bls.TryExportBLSPublicKey(publicKeyBytes, out var publicKeybytesWritten);
                var publicKey = new BlsPublicKey(publicKeyBytes);

                // Withdrawal Credentials
                var withdrawalCredentialBytes = _cryptographyService.Hash(publicKey.AsSpan()).AsSpan().ToArray();
                withdrawalCredentialBytes[0] = initialValues.BlsWithdrawalPrefix;
                var withdrawalCredentials = new Hash32(withdrawalCredentialBytes);

                // Build deposit data
                var depositData = new DepositData(publicKey, withdrawalCredentials, amount);

                // Sign deposit data
                var depositDataSigningRoot = depositData.SigningRoot();
                var domain      = _beaconChainUtility.ComputeDomain(signatureDomains.Deposit);
                var destination = new Span <byte>(new byte[96]);
                bls.TrySignHash(depositDataSigningRoot.AsSpan(), destination, out var bytesWritten, domain.AsSpan());
                var depositDataSignature = new BlsSignature(destination);
                depositData.SetSignature(depositDataSignature);

                // Deposit

                // TODO: This seems a very inefficient way (copied from tests) as it recalculates the merkle tree each time
                // (you only need to add one node)

                // TODO: Add some tests around quick start, then improve

                var index = depositDataList.Count;
                depositDataList.Add(depositData);
                var root        = depositDataList.HashTreeRoot((ulong)1 << _chainConstants.DepositContractTreeDepth);
                var allLeaves   = depositDataList.Select(x => x.HashTreeRoot());
                var tree        = CalculateMerkleTreeFromLeaves(allLeaves);
                var merkleProof = GetMerkleProof(tree, index, 32);
                var proof       = new List <Hash32>(merkleProof);
                var indexBytes  = new Span <byte>(new byte[32]);
                BitConverter.TryWriteBytes(indexBytes, (ulong)index + 1);
                if (!BitConverter.IsLittleEndian)
                {
                    indexBytes.Slice(0, 8).Reverse();
                }
                var indexHash = new Hash32(indexBytes);
                proof.Add(indexHash);
                var leaf = depositData.HashTreeRoot();
                _beaconChainUtility.IsValidMerkleBranch(leaf, proof, _chainConstants.DepositContractTreeDepth + 1, (ulong)index, root);
                var deposit = new Deposit(proof, depositData);

                _logger.LogDebug("Quick start adding deposit for mocked validator {ValidatorIndex} with public key {PublicKey}.",
                                 validatorIndex, publicKey);

                deposits.Add(deposit);
            }

            var genesisState = _beaconChain.InitializeBeaconStateFromEth1(quickStartParameters.Eth1BlockHash, quickStartParameters.Eth1Timestamp, deposits);

            // We use the state directly, and don't test IsValid
            genesisState.SetGenesisTime(quickStartParameters.GenesisTime);
            var store = _forkChoice.GetGenesisStore(genesisState);

            _logger.LogDebug("Quick start genesis store created with genesis time {GenesisTime}.", store.GenesisTime);
        }