Skip to content

Conversation

@YakupIpek
Copy link
Contributor

The stratisproject/StratisBitcoinFullNode#4194 moved here.

This pr needs to have package from stratisproject/Stratis.SmartContracts#13

This pr has been reviewed actually and should to be complete but it was require to have hard-fork because upgrade needed on Stratis.SmartContracts assemblies.

Basically EcRecoverProvider.SignMessage(privateKey, message) returns a signature that we can recover PubKey address and we can do this via ECRecoverProvider.GetSigner(message, offChainSignature) in the smart contract code.

I reviewed&tested it and i don't have anything to add.

I am going to remove dev prefix from version(2.0.1-dev) if it is approved.

codingupastorm and others added 10 commits February 8, 2021 15:42
# Conflicts:
#	src/Stratis.Bitcoin.Features.SmartContracts.Tests/Stratis.Bitcoin.Features.SmartContracts.Tests.csproj
#	src/Stratis.Bitcoin.Features.SmartContracts/Stratis.Bitcoin.Features.SmartContracts.csproj
#	src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj
Copy link
Contributor

@quantumagi quantumagi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Can merge when CI passes.

/// <returns>The base58 address for the signer of a signature.</returns>
public Address GetSigner(byte[] message, byte[] signature)
{
// TODO: Error handling for incorrect signature format etc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be resolved before this can be used in production.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rowandh PubKey.RecoverCompact already detects incorrect format and raise an exception.

There is something else to do in here ?

@quantumagi
Copy link
Contributor

quantumagi commented Apr 7, 2021

Perhaps include support for VerifySignatures into this PR. See https://github.com/stratisproject/Stratis.SmartContracts/blob/1d30c10805b7b2b4c77440068642614394c54b28/Stratis.SmartContracts/IEcRecoverProvider.cs.

        private byte[][] DeserializeSignatures(byte[] signatures)
        {
            const int signatureLength = 65;
            const int minHeaderByte = 27;
            const int maxHeaderByte = 34;
            int cnt = signatures.Length / signatureLength;
            Guard.Assert(signatures.Length == signatureLength * cnt);
            var buffer = new byte[cnt][];
            for (int i = 0; i < cnt; i++)
            {
                Array.Copy(signatures, i * signatureLength, buffer[i], 0, signatureLength);
                Guard.Assert(buffer[i][0] >= minHeaderByte && buffer[i][0] <= maxHeaderByte);
            }
            return buffer;
        }

        /// <summary>
        /// Takes a message and signatures and returns the list of addresses that produced the signatures.
        /// </summary>
        /// <param name="message">The message that was signed.</param>
        /// <param name="signatures">The list of signatures of the message.</param>
        /// <param name="addresses">If not <c>null</c> the addresses returned are intersected with these addresses.</param>
        /// <returns>The list of addresses that produced the signatures and constrained to the list provided in <paramref name="addresses"/> if not <c>null</c>.</returns>
        public Address[] VerifySignatures(byte[] signatures, byte[] message, Address[] addresses = null)
        {
            Guard.NotNull(message, nameof(message));
            Guard.NotNull(signatures, nameof(signatures));
            var keyIds = DeserializeSignatures(signatures)
                .Select(s => PubKey.RecoverFromMessage(message, Encoders.Base64.EncodeData(s)).Hash);
            if (addresses != null)
                keyIds = keyIds.Intersect(addresses.Select(a => new KeyId(a.ToBytes())));
            return keyIds.Select(s => s.ToBytes().ToAddress()).ToArray();
        }

uint256 hashedUint256 = GetUint256FromMessage(message);
PubKey pubKey = PubKey.RecoverCompact(hashedUint256, signature);

return pubKey.GetAddress(this.network).ToString().ToAddress(this.network);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this conversion can be done without using this.network.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants