Пример #1
0
        public void Ed25519_precompile_can_verify_correct_sig()
        {
            HashProvider hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256"));

            FfiWrapper  cryptoContext         = new FfiWrapper();
            IPrivateKey signingPrivateKey     = cryptoContext.GeneratePrivateKey();
            var         signingPublicKeyBytes = signingPrivateKey.GetPublicKey().Bytes;

            var byteCode = PrepareEd25519PrecompileCall(hashProvider, cryptoContext, signingPrivateKey, signingPrivateKey);

            GethLikeTxTracer       txTracer   = RunVirtualMachine(byteCode);
            EthereumJsonSerializer serializer = new EthereumJsonSerializer();
            GethLikeTxTrace        trace      = txTracer.BuildResult();

            TestContext.WriteLine(serializer.Serialize(trace, true));
            trace.Entries.Last().Stack.First().Should().Be("0000000000000000000000000000000000000000000000000000000000000001");
            trace.Entries.Last().Memory.First().Should().StartWith("01");
        }
Пример #2
0
        private byte[] PrepareEd25519PrecompileCall(HashProvider hashProvider, FfiWrapper cryptoContext, IPrivateKey signingPrivateKey, IPrivateKey otherPrivateKey)
        {
            var data    = Encoding.UTF8.GetBytes("Testing testing 1 2 3");
            var message = hashProvider.ComputeMultiHash(data).Digest;

            var signingContext = Encoding.UTF8.GetBytes("Testing testing 1 2 3 context");
            var context        = hashProvider.ComputeMultiHash(signingContext).Digest;

            ISignature signature      = cryptoContext.Sign(signingPrivateKey, message, context);
            var        signatureBytes = signature.SignatureBytes;
            var        publicKeyBytes = otherPrivateKey.GetPublicKey().Bytes;

            // below verify check is not needed but allows for greater confidence for any person in the future
            // that would approach and debug test when it goes wrong
            // =====================================================
            cryptoContext.Verify(signature, message, context)
            .Should().BeTrue("signature generated with private key should verify with corresponding public key");

            // =====================================================

            // save message hash in memory at position 0x00
            string pushToMemoryAt0 = "7f" + message.ToHexString(false) + "600052";

            // save first 32 bytes of the sig in memory starting from position 0x20
            string pushToMemoryAt32 = "7f" + signatureBytes.AsSpan(0, 32).ToHexString(false) + "602052";

            // save remaining 32 bytes of the sig in memory starting from position 0x40
            string pushToMemoryAt64 = "7f" + signatureBytes.AsSpan(32, 32).ToHexString(false) + "604052";

            // save context bytes in memory starting from position 0x60 (but this should be changed if context is smaller)
            string pushToMemoryAt96 = "7f" + context.ToHexString(false) + "606052";

            // save public key bytes in memory starting from position 0x80 (but this should be changed if context is smaller)
            string pushToMemoryAt128 = "7f" + publicKeyBytes.ToHexString(false) + "608052";

            // address of the precompile within Catalyst
            string addressCode = GetEd25519PrecompileAddressAsHex();

            var byteCode = Bytes.FromHexString(
                pushToMemoryAt0 +
                pushToMemoryAt32 +
                pushToMemoryAt64 +
                pushToMemoryAt96 +
                pushToMemoryAt128 +

                // PUSH1 32 PUSH1 0 PUSH1 160 PUSH1 0 PUSH20 address GAS STATICCALL
                // make a call to precompile and pass [0,160) bytes of memory as an input
                // and store result at [0,1) of memory array
                // allow precompile to use all the gas required
                "6001600060a0600073" +
                addressCode +
                "45fa00");

            TestContext.WriteLine(byteCode.ToHexString());
            return(byteCode);
        }