add secp256k1 + keccak256 to signature verification.#3205
add secp256k1 + keccak256 to signature verification.#3205Jim8y wants to merge 8 commits intoneo-project:masterfrom
Conversation
…-secp256k1 # Conflicts: # src/Neo/Cryptography/Crypto.cs # src/Neo/SmartContract/ApplicationEngine.Crypto.cs
| protected internal readonly static Dictionary<byte, ECCurve> ECCurveSelection = new(){ | ||
| { 0x00, ECCurve.Secp256r1 }, | ||
| { 0x01, ECCurve.Secp256k1 }, | ||
| }; | ||
|
|
There was a problem hiding this comment.
(This may not be the best place to put this dictionary)
Hey @roman-khimov, this feature is required by some exchanges that only support secp256k1 to sign transactions, its hardware restrained and can not be updated. Thus, we need to add support to verify secp256k1 signed transactions. But we only verify it, we dont construct it. |
|
How come it wasn't a problem for years of Neo existence? This raises so many compatibility questions that I don't even know where to begin. Addresses/wallets/script parsers/NeoFS accounts/NeoX accounts. Likely the issue can be solved with |
New syscall:System.Crypto.CheckSigV2 System.Crypto.CheckMultisigV2 Data Type: InvocationScript: Old format Curve: 0x00 r1, Hash: 0x00 SHA256, Exampe: using ScriptBuilder verificationScriptBuilder = new();
verificationScriptBuilder.EmitRaw([0x01]); // Push curve secp256K1
verificationScriptBuilder.EmitRaw([0x01]); // Push Keccak256 hasher
verificationScriptBuilder.EmitPush(pubKey); // Push pubkey
verificationScriptBuilder.EmitSysCall(ApplicationEngine.System_Crypto_CheckSigV2);Price:SignatureContractCostV2: MultiSignatureContractCostV2: How to check if a verification script is V2: private static ReadOnlySpan<byte> ParseScriptV2(ReadOnlySpan<byte> script, out bool? isV2, out ECCurve? curve, out Hasher? hasher)
{
if (script.Length < 40) throw new FormatException("The verification script is too short.");
isV2 = BinaryPrimitives.ReadUInt32LittleEndian(script[^4..]) == ApplicationEngine.System_Crypto_CheckSigV2 ||
BinaryPrimitives.ReadUInt32LittleEndian(script[^4..]) == ApplicationEngine.System_Crypto_CheckMultisigV2;
curve = ECCurve.Secp256r1;
hasher = Hasher.SHA256;
if (!isV2.Value)
{
return script;
}
curve = script[0] == 0x01 ? ECCurve.Secp256k1 : ECCurve.Secp256r1;
hasher = script[1] == 0x01 ? Hasher.Keccak256 : Hasher.SHA256;
return script[2..];
} |
|
Note: Still need to add it to the hard fork. |
|
|
||
| public static byte[] Keccak256(this ReadOnlySpan<byte> value) | ||
| { | ||
| return Keccak256(value.ToArray()); |
There was a problem hiding this comment.
| return Keccak256(value.ToArray()); | |
| return Keccak256([.. value]); |
|
|
||
| public static byte[] Keccak256(this Span<byte> value) | ||
| { | ||
| return Keccak256(value.ToArray()); |
There was a problem hiding this comment.
| return Keccak256(value.ToArray()); | |
| return Keccak256([.. value]); |
| for (int i = 0; i < hashes.Length; i++) | ||
| { | ||
| if (IsSignatureContract(witnesses[i].VerificationScript.Span)) | ||
| if (IsSignatureContract(witnesses[i].VerificationScript.Span, out bool? isV2, out ECCurve? curve, out Hasher? hasher)) |
There was a problem hiding this comment.
Dont add ? nullable until project is convert to nullable project.
| { | ||
| if (hashes[i] != witnesses[i].ScriptHash) return VerifyResult.Invalid; | ||
| var pubkey = witnesses[i].VerificationScript.Span[2..35]; | ||
| var pubkey = isV2.Value ? witnesses[i].VerificationScript.Span[4..37] : witnesses[i].VerificationScript.Span[2..35]; |
There was a problem hiding this comment.
| var pubkey = isV2.Value ? witnesses[i].VerificationScript.Span[4..37] : witnesses[i].VerificationScript.Span[2..35]; | |
| var pubkey = isV2.Value ? witnesses[i].VerificationScript[4..37] : witnesses[i].VerificationScript[2..35]; |
| try | ||
| { | ||
| if (!Crypto.VerifySignature(this.GetSignData(settings.Network), witnesses[i].InvocationScript.Span[2..], pubkey, ECCurve.Secp256r1)) | ||
| if (!Crypto.VerifySignature(this.GetSignData(settings.Network), witnesses[i].InvocationScript.Span[2..], pubkey, curve, hasher.Value)) |
There was a problem hiding this comment.
| if (!Crypto.VerifySignature(this.GetSignData(settings.Network), witnesses[i].InvocationScript.Span[2..], pubkey, curve, hasher.Value)) | |
| if (!Crypto.VerifySignature(this.GetSignData(settings.Network), witnesses[i].InvocationScript[2..], pubkey, curve, hasher.Value)) |
| } | ||
| } | ||
| else if (IsMultiSigContract(witnesses[i].VerificationScript.Span, out var m, out ECPoint[] points)) | ||
| else if (IsMultiSigContract(witnesses[i].VerificationScript.Span, out var m, out ECPoint[] points, out isV2, out curve, out hasher)) |
There was a problem hiding this comment.
| else if (IsMultiSigContract(witnesses[i].VerificationScript.Span, out var m, out ECPoint[] points, out isV2, out curve, out hasher)) | |
| else if (IsMultiSigContract(witnesses[i].VerificationScript, out var m, out ECPoint[] points, out isV2, out curve, out hasher)) |
Just to be in sync with Discord: we've discussed it with @roman-khimov and prepared an alternative concept that do not require core protocol modifications and do not require custom verification contract deployment. The solution is rather simple: use custom witness verification script with a call to native CryptoLib's |
|
Can't they use |
|
It's possible to use his |
A port of nspcc-dev/neo-go@1e2b438. This commit contains minor protocol extension needed for custom Koblitz-based verification scripts (an alternative to #3205). Replace native CryptoLib's verifyWithECDsa `curve` parameter by `curveHash` parameter which is a enum over supported pairs of named curves and hash functions. Even though this change is a compatible extension of the protocol, it changes the genesis state due to parameter renaming (CryptoLib's manifest is changed). But we're going to resync chain in 3.7 release anyway, so it's not a big deal. Also, we need to check mainnet and testnet compatibility in case if anyone has ever called verifyWithECDsa with 24 or 25 `curve` value. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Koblitz-based and Keccak-based transaction witness verification for single signature and multisignature ported from nspcc-dev/neo-go#3425. An alternative to #3205. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
A port of nspcc-dev/neo-go@1e2b438. This commit contains minor protocol extension needed for custom Koblitz-based verification scripts (an alternative to #3205). Replace native CryptoLib's verifyWithECDsa `curve` parameter by `curveHash` parameter which is a enum over supported pairs of named curves and hash functions. NamedCurve enum mark as deprecated and replaced by NamedCurveHash with compatible behaviour. Even though this change is a compatible extension of the protocol, it changes the genesis state due to parameter renaming (CryptoLib's manifest is changed). But we're going to resync chain in 3.7 release anyway, so it's not a big deal. Also, we need to check mainnet and testnet compatibility in case if anyone has ever called verifyWithECDsa with 24 or 25 `curve` value. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Koblitz-based and Keccak-based transaction witness verification for single signature and multisignature ported from nspcc-dev/neo-go#3425. An alternative to #3205. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
…#3209) * Native: extend CryptoLib's verifyWithECDsa with hasher parameter A port of nspcc-dev/neo-go@1e2b438. This commit contains minor protocol extension needed for custom Koblitz-based verification scripts (an alternative to #3205). Replace native CryptoLib's verifyWithECDsa `curve` parameter by `curveHash` parameter which is a enum over supported pairs of named curves and hash functions. NamedCurve enum mark as deprecated and replaced by NamedCurveHash with compatible behaviour. Even though this change is a compatible extension of the protocol, it changes the genesis state due to parameter renaming (CryptoLib's manifest is changed). But we're going to resync chain in 3.7 release anyway, so it's not a big deal. Also, we need to check mainnet and testnet compatibility in case if anyone has ever called verifyWithECDsa with 24 or 25 `curve` value. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * SmartContract: add extension to ScriptBuilder for System.Contract.Call Group the set of common operations required to emit System.Contract.Call appcall. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * Native: add an example of custom Koblitz signature verification Koblitz-based and Keccak-based transaction witness verification for single signature and multisignature ported from nspcc-dev/neo-go#3425. An alternative to #3205. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * SmartContract: make multisig koblitz easier to parse 1. Make prologue be exactly the same as regular CheckMultisig. 2. But instead of "SYSCALL System.Crypto.CheckMultisig" do INITSLOT and K check. 3. This makes all of the code from INITSLOT below be independent of N/M, so one can parse the script beginning in the same way CheckMultisig is parsed and then just compare the rest of it with some known-good blob. 4. The script becomes a tiny bit larger now, but properties above are too good. Ported from nspcc-dev/neo-go@34ee294. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * SmartContract: use ABORT in Koblitz multisig Make the script a bit shorter. ABORTMSG would cost a bit more. Ported from nspcc-dev/neo-go@fb16891. Ref. nspcc-dev/neo-go#3425 (comment). Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * SmartContract: reduce callflag scope for Koblitz verification scripts All flag is too wide. A port of nspcc-dev/neo-go@fe292f3. Ref. nspcc-dev/neo-go#3425 (comment). Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * Native: add tests for CryptoLib's verifyWithECDsa No functional changes, just add more unit-tests. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * Native: update NamedCurveHash values for Keccak256 hasher Use 122 and 123 respectively for secp256k1Keccak256 and secp256r1Keccak256. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * SmartContract: move EmitAppCallNoArgs to the testing code We're not going to implement custom Koblitz witness generation at the core, and thus, the only user of this API is testing code. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * Apply suggestions from code review clean ut lines * fix names * Cryptography: cache ECDomainParameters for Secp256r1 and Secp256k1 Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs * Update tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs --------- Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> Co-authored-by: Shargon <shargon@gmail.com> Co-authored-by: Jimmy <jinghui@wayne.edu>
|
Close because of #3209 |
Description
This pr focus on adding support to secp256k1 signed transactions and hashed with Keccak256.
Fixes # (issue)
Type of change
How Has This Been Tested?
Test Configuration:
Checklist: