Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

native: add test for custom Koblitz witness verification script #3425

Merged
merged 11 commits into from May 13, 2024

Conversation

AnnaShaleva
Copy link
Member

@AnnaShaleva AnnaShaleva commented Apr 27, 2024

Every single thing is already implemented in the protocol for Koblitz verification scripts. An alternative to neo-project/neo#3205.

A note for reviewers

This PR contains a large number of file changes, but two most important files are:

  • Native CryptoLib's verifyWithECDsa extension (./pkg/core/native/crypto.go file);
  • Custom witness scripts builder (./pkg/core/native/native_test/cryptolib_verificacation_test.go file);

Single signature verification

What user signs Invocation script length Verification script length Witness verification cost*
keccak256([4-bytes-network-magic-LE, txHash-bytes-BE])** 66 bytes 110 bytes 2154270 GAS
keccak256([var-bytes-network-magic, txHash-bytes-BE]) 66 bytes 98 bytes 2092530 GAS
keccak256([var-bytes-network-magic, txHash-bytes-BE]) (static magic) 66 bytes 95 bytes 2092320 GAS
keccak256(sha256([var-bytes-network-magic, txHash-bytes-BE])) 66 bytes 136 bytes 4120620 GAS
keccak256(sha256([4-bytes-network-magic-LE, txHash-bytes-BE])) 66 bytes 186 bytes 5116020 GAS

* Verification cost is based on the default execution fee value.
** The proposed verification method. Other methods are less preferable and are added for comparison.

Multisignature verification

What user signs Multisig M out of N Invocation script length Verification script length Witness verification cost*
keccak256([4-bytes-network-magic-LE, txHash-bytes-BE])** 3 out of 4 198 bytes (= 66*3 bytes) 264 bytes 8390070 GAS

* Verification cost is based on the default execution fee value.
** The proposed verification method. Other methods are less preferable and are added for comparison.

@roman-khimov, let's review&improve&merge, and after that I may create a comment in the core repo (or even an issue).

Copy link

codecov bot commented Apr 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 86.16%. Comparing base (b21db99) to head (e275495).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3425      +/-   ##
==========================================
+ Coverage   86.12%   86.16%   +0.04%     
==========================================
  Files         332      332              
  Lines       38435    38443       +8     
==========================================
+ Hits        33102    33125      +23     
+ Misses       3804     3793      -11     
+ Partials     1529     1525       -4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@roman-khimov roman-khimov left a comment

Choose a reason for hiding this comment

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

I think it's viable. Minor improvements can be done, but overall it's something that can be discussed.

@Jim8y
Copy link

Jim8y commented Apr 28, 2024

@AnnaShaleva I have no preference to solutions, yours here is much more elegent, i can close mine when you are done. But please make it:

  1. support both SHA256 and Keccak256 hasher. 2. support multi-sig. 3. Update the corresponding costs.

Erik has asked to make it scalable, but i think currently we can only focus on dealing k1.

And we will need to help COZ to update their neojs SDK as well as other SDKs from other communities.

@AnnaShaleva
Copy link
Member Author

Let it be here, CryptoLib extension is there, and I'm still working on the multisignature verification script, will update soon.

AnnaShaleva added a commit that referenced this pull request May 2, 2024
It's based on the constant-length network magic, ref.
#3425 (comment).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
@AnnaShaleva
Copy link
Member Author

AnnaShaleva commented May 2, 2024

@roman-khimov, multisignature version is ready, let's review and improve it (a couple of TODOs are there, we need to decide about them). But overall the algorithm works as expected and is quite clear.

Meanwhile I'll add results for other multisig combinations and port CryptoLib's change to the C# repo.

pkg/crypto/hash/hash.go Outdated Show resolved Hide resolved
pkg/core/native/crypto.go Outdated Show resolved Hide resolved
@@ -46,6 +50,17 @@ func DoubleSha256(data []byte) util.Uint256 {
return hash
}

// Keccak256 hashes the incoming byte slice using the
// keccak256 algorithm.
func Keccak256(data []byte) util.Uint256 {
Copy link
Member

Choose a reason for hiding this comment

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

Please leave it internal to native contract. pkg/crypto is about proper Neo stuff, importing keccak there won't be correct.

Copy link
Member Author

Choose a reason for hiding this comment

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

But Keccak256 is a proper Neo stuff, and it's not related to the Koblitz-based witnesses. We have keccak256 method in CryptoLib, so it's a part of Neo.

Are you sure we need to keep it inside CryptoLib?

Copy link
Member

Choose a reason for hiding this comment

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

Not exactly. It is available in VM, but you only need it for compatibility with E-chain. And there is zero Neo specifics wrt this hash handling (like Hash160 or DoubleSha256). Yes, it reminds of RipeMD160 in some ways, but you can't have accounts without it. Keccak is different, you can live a happy life without it.

I'm mostly concerned about dependency management here.

Copy link
Member

Choose a reason for hiding this comment

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

Still there, but it's NeoGo-specific.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

pkg/core/native/native_test/cryptolib_verification_test.go Outdated Show resolved Hide resolved
pkg/core/native/native_test/cryptolib_verification_test.go Outdated Show resolved Hide resolved
pkg/core/native/native_test/cryptolib_verification_test.go Outdated Show resolved Hide resolved
pkg/core/native/native_test/cryptolib_verification_test.go Outdated Show resolved Hide resolved
pkg/core/native/native_test/cryptolib_verification_test.go Outdated Show resolved Hide resolved
@roman-khimov
Copy link
Member

Multisignature is interesting wrt calculatenetworkfee, btw. I'm sure our implementation can handle simple signature case, but multisig cost currently depends on correct/incorrect flow (and POPITEM from #3425 (comment) can make it worse), so we can have a trouble estimating verification cost for it.

AnnaShaleva added a commit that referenced this pull request May 3, 2024
It's based on the constant-length network magic, ref.
#3425 (comment).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Copy link
Member

@roman-khimov roman-khimov left a comment

Choose a reason for hiding this comment

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

I think we have both simple and multisig working fine at this stage. Simple sig is perfect to me. Multisig can be changed in very minor details, but those are opinionated. Current code is pretty simple and clear, can be reviewed easily. Let's port to C# and collect more feedback.

pkg/core/native/native_test/cryptolib_verification_test.go Outdated Show resolved Hide resolved
@AnnaShaleva AnnaShaleva force-pushed the cryptolib-test branch 3 times, most recently from 75020b1 to fdc3923 Compare May 4, 2024 12:30
AnnaShaleva added a commit to neo-project/neo that referenced this pull request May 6, 2024
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>
AnnaShaleva added a commit to neo-project/neo that referenced this pull request May 6, 2024
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>
AnnaShaleva added a commit to neo-project/neo that referenced this pull request May 6, 2024
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>
AnnaShaleva added a commit to neo-project/neo that referenced this pull request May 6, 2024
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>
AnnaShaleva added a commit to neo-project/neo that referenced this pull request May 6, 2024
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>
NGDAdmin pushed a commit to neo-project/neo that referenced this pull request May 10, 2024
…#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>
@roman-khimov
Copy link
Member

Conflicts.

AnnaShaleva and others added 9 commits May 13, 2024 09:27
Every single thing is already implemented in the protocol for Koblitz
verification scripts.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
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. 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>
It's needed for tests and further custom verification script build.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
It's based on the constant-length network magic, ref.
#3425 (comment).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Value calculated by calculatenetworkfee is enough to pass the real
tx verification. However, network fee may be decreased, so calculations
are not quite accurate. Need to investigate, why.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
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.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Make the script a bit shorter. ABORTMSG would cost a bit more.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
callflag.All is too wide.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Use 122 and 123 respectively for Secp256k1Keccak256 and
Secp256r1Keccak256, ref.
neo-project/neo#3209 (comment).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
@AnnaShaleva AnnaShaleva marked this pull request as ready for review May 13, 2024 07:17
@roman-khimov roman-khimov merged commit 02ecbeb into master May 13, 2024
21 checks passed
@roman-khimov roman-khimov deleted the cryptolib-test branch May 13, 2024 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
test Unit tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants