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

Kwxm/signature verification throughput statistics #4883

Merged
merged 8 commits into from
Oct 13, 2022

Conversation

kwxm
Copy link
Contributor

@kwxm kwxm commented Oct 5, 2022

(PLT-788) @iquerejeta is interested in how many Ed25519 signatures we can verify in a Plutus validation script. This adds a program to test that. I don't know if we want to merge it, but here it is anyway.

It does the following, which I think is roughly what Iñigo's interested in.

  • Generates n public keys P_1,...,P_n

  • Hashes them to get n hashes H_1,...,H_n.

  • Signs all of the hashes with different private keys K_1,...,K_n (with corresponding public keys V_1,...V_n) to get n
    signatures S_1,...,S_n.

  • Creates a list of (V_i, H_i, S_i, P_i) tuples, convert it to Data, and feeds that to a script which

    1. Verifies each (V_i, H_i, S_i) to check that the signatures are valid.
    2. Hashes each P_i to make sure that it matches H_i.

This program does that for varying values of n and prints statistics about the size, cpu cost, and memory cost of the script. The hashes are calculated using sha2_256; I also tried sha3_256 and that left the script sizes unaltered but increased CPU/memory usage by 1 or 2%.

The results are shown below, both as absolute values and as percentages of the limits specified in the current protocol parameters. For script size, I've shown the percentage of the max_tx_size parameter: this may include more than just the script, so the percentages may be a little optimistic. Anyway the main limiting factor seems to be the script size: we can get up to 90 or so signatures before we start to hit the limit. The data that we're checking account for most of the size of the script; I may have included too much stuff in the inputs, and if that's the case then it may be possible to squeeze in some more.

    n     script size             CPU usage               Memory usage
  ----------------------------------------------------------------------
    0     507   (3.1%)         7834416   (0.1%)           28414   (0.2%) 
   10    2234  (13.6%)       781835316   (7.8%)          667844   (4.8%) 
   20    3961  (24.2%)      1555836216  (15.6%)         1307274   (9.3%) 
   30    5688  (34.7%)      2329837116  (23.3%)         1946704  (13.9%) 
   40    7415  (45.3%)      3103838016  (31.0%)         2586134  (18.5%) 
   50    9141  (55.8%)      3877838916  (38.8%)         3225564  (23.0%) 
   60   10868  (66.3%)      4651839816  (46.5%)         3864994  (27.6%) 
   70   12595  (76.9%)      5425840716  (54.3%)         4504424  (32.2%) 
   80   14321  (87.4%)      6199841616  (62.0%)         5143854  (36.7%) 
   90   16048  (97.9%)      6973842516  (69.7%)         5783284  (41.3%) 
  100   17775 (108.5%)      7747843416  (77.5%)         6422714  (45.9%) 
  110   19502 (119.0%)      8521844316  (85.2%)         7062144  (50.4%) 
  120   21228 (129.6%)      9295845216  (93.0%)         7701574  (55.0%) 
  130   22955 (140.1%)     10069846116 (100.7%)         8341004  (59.6%) 
  140   24682 (150.6%)     10843847016 (108.4%)         8980434  (64.1%) 
  150   26409 (161.2%)     11617847916 (116.2%)         9619864  (68.7%) 

@kwxm
Copy link
Contributor Author

kwxm commented Oct 5, 2022

Hmmm. It's failing in CI because cabal seems to think that plutus-tx-plugin isn't required, but if I remove that from the cabal file I get a linker error (locally, at least).

@iquerejeta
Copy link
Contributor

This is great. Thanks a lot for the benchmarks. They are really helpful to define our strategy in the near future. I guess the decision of merging or not will fall back to the plutus team, but I find these really helpful, and wouldn't be surprised if they'll be helpful in the future.

The fact that the script size is the bottleneck gives hopes that we can design the protocol in a way where we optimise the script size by a fraction. However, the CPU usage seems to indicate that the hard limit is at around 130 signatures (this assuming we don't do anything else in the script), which is also very good to know.

@michaelpj
Copy link
Contributor

Hmmm. It's failing in CI because cabal seems to think that plutus-tx-plugin isn't required, but if I remove that from the cabal file I get a linker error (locally, at least).

Yeah, this is a weird thing that happens sometimes, just turn off -Wunused-packges for that component with a note.

Copy link
Contributor

@michaelpj michaelpj left a comment

Choose a reason for hiding this comment

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

LGTM!

@@ -0,0 +1,213 @@
-- editorconfig-checker-disable-file
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 we probably want to avoid introducing more of this :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, I thought we had to put that in. How do we decide if it's necessary or not then?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmph, I thought I had documetned this in CONTRIBUTING but apparently not. You only need this if editorconfig-checker complains at you and you're unwilling to fix it. I mostly put it in to grandfather in old files so I wouldn't have to fix literally everything.


-- Create a list containing m bytestrings of length n (also terrible)
listOfSizedByteStrings :: Integer -> Integer -> [ByteString]
listOfSizedByteStrings m n = unsafePerformIO . G.sample $
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use genSample that you just wrote?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just copied it in from elsewhere and didn't pay too much attentiion to what it was doing! I'll tidy it up though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

genSample is unused anyway. I'll just remove it.

plutus-benchmark/ed25519-throughput/Main.hs Outdated Show resolved Hide resolved
mkInputsAsData :: Integer -> HashFun -> BuiltinData
mkInputsAsData n hash = Tx.dataToBuiltinData $ toData (mkInputs @Ed25519DSIGN n id hash)

-- Check conditions (1) and (2) mentioned above. We check these for all of the
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
-- Check conditions (1) and (2) mentioned above. We check these for all of the
-- | Check conditions (1) and (2) mentioned above. We check these for all of the

not that it matters, just might as well make actual haddock comments

Copy link
Contributor

Choose a reason for hiding this comment

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

throughout

verifyInputs hash d =
case Tx.fromBuiltinData d of
Nothing -> Tx.error ()
Just (Inputs inputs) -> ver inputs True
Copy link
Contributor

Choose a reason for hiding this comment

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

we have all defined somewhere also, but this is more "bare metal" I guess

convert it to Data, and feed that to a script which

1. Verifies each (V_i, H_i, S_i) to check that the signatures are valid.
2. Hashes each P_i to make sure that it matches H_i.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this something we actually need to do? do we not just work with the hashes normally? question for @iquerejeta probably

Tx.getPlc $ $$(Tx.compile [|| verifyInputs Tx.sha2_256 ||]) `Tx.applyCode` Tx.liftCode (mkInputsAsData n Hash.sha2_256)


-- Protocol parameters (November 2022)
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should put this somewhere common in case we want to compare other stuff to it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure what you mean. Put what somewhere common?

Copy link
Contributor

Choose a reason for hiding this comment

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

These numbers corresponding to protocol parameters to test against. E.g. we have some tests that check for script sizes, we might want to also show what fraction of the max size they occupy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see. We'd have to keep them updated. I wonder if there's anywhere we can look them up automatically? I just googled and got them from https://adapools.org/protocol-parameters.

Copy link
Contributor

Choose a reason for hiding this comment

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

They don't have to be super up-to-date, it's fine to have some approximately-right numbers for things like this, I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll make a ticket for that. I'm not sure where else we might want these and working that out's not very relevant to this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

PLT-986

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved those to near the top of the file so that they're easier to find.

@kwxm
Copy link
Contributor Author

kwxm commented Oct 13, 2022

OK, I'm going to merge this. It seems that it's just Cicero that's problematic.

@kwxm kwxm merged commit 511611c into master Oct 13, 2022
@kwxm kwxm deleted the kwxm/signature-verification-throughput-statistics branch October 13, 2022 02:40
@kwxm
Copy link
Contributor Author

kwxm commented Nov 7, 2022

For reference, here are the earlier figures along with ones for verifySchnorrSecp256k1Signature and verifyEcdsaSecp256k1Signature. The figures for script sizes are pretty much the same (as you'd expect), but the CPU figures are better since both of the Secp256k1 functions have lower costs than the Ed25519 one. Also, most of the space in the script is taken up by the data, so things might be different in a real application. These figures were generated using the cost model at this state of the repository.

verifyEd25519Signature

    n     script size             CPU usage               Memory usage
  ----------------------------------------------------------------------
    0     507   (3.1%)         7834416   (0.1%)           28414   (0.2%) 
   10    2234  (13.6%)       781835316   (7.8%)          667844   (4.8%) 
   20    3961  (24.2%)      1555836216  (15.6%)         1307274   (9.3%) 
   30    5688  (34.7%)      2329837116  (23.3%)         1946704  (13.9%) 
   40    7415  (45.3%)      3103838016  (31.0%)         2586134  (18.5%) 
   50    9141  (55.8%)      3877838916  (38.8%)         3225564  (23.0%) 
   60   10868  (66.3%)      4651839816  (46.5%)         3864994  (27.6%) 
   70   12595  (76.9%)      5425840716  (54.3%)         4504424  (32.2%) 
   80   14321  (87.4%)      6199841616  (62.0%)         5143854  (36.7%) 
   90   16048  (97.9%)      6973842516  (69.7%)         5783284  (41.3%) 
  100   17775 (108.5%)      7747843416  (77.5%)         6422714  (45.9%) 
  110   19502 (119.0%)      8521844316  (85.2%)         7062144  (50.4%) 
  120   21228 (129.6%)      9295845216  (93.0%)         7701574  (55.0%) 
  130   22955 (140.1%)     10069846116 (100.7%)         8341004  (59.6%) 
  140   24682 (150.6%)     10843847016 (108.4%)         8980434  (64.1%) 
  150   26409 (161.2%)     11617847916 (116.2%)         9619864  (68.7%) 

verifySchnorrSecp256k1Signature

 ----------------------------------------------------------------------
    0     499   (3.0%)         7765416   (0.1%)           28114   (0.2%) 
   10    2226  (13.6%)       589337056   (5.9%)          652544   (4.7%) 
   20    3953  (24.1%)      1170908696  (11.7%)         1276974   (9.1%) 
   30    5680  (34.7%)      1752480336  (17.5%)         1901404  (13.6%) 
   40    7407  (45.2%)      2334051976  (23.3%)         2525834  (18.0%) 
   50    9133  (55.7%)      2915623616  (29.2%)         3150264  (22.5%) 
   60   10860  (66.3%)      3497195256  (35.0%)         3774694  (27.0%) 
   70   12587  (76.8%)      4078766896  (40.8%)         4399124  (31.4%) 
   80   14313  (87.4%)      4660338536  (46.6%)         5023554  (35.9%) 
   90   16040  (97.9%)      5241910176  (52.4%)         5647984  (40.3%) 
  100   17767 (108.4%)      5823481816  (58.2%)         6272414  (44.8%) 
  110   19494 (119.0%)      6405053456  (64.1%)         6896844  (49.3%) 
  120   21220 (129.5%)      6986625096  (69.9%)         7521274  (53.7%) 
  130   22947 (140.1%)      7568196736  (75.7%)         8145704  (58.2%) 
  140   24674 (150.6%)      8149768376  (81.5%)         8770134  (62.6%) 
  150   26401 (161.1%)      8731340016  (87.3%)         9394564  (67.1%) 

verifyEcdsaSecp256k1Signature

    n     script size             CPU usage               Memory usage
  ----------------------------------------------------------------------
    0     499   (3.0%)         7765416   (0.1%)           28114   (0.2%) 
   10    2246  (13.7%)       549033716   (5.5%)          652544   (4.7%) 
   20    3993  (24.4%)      1090302016  (10.9%)         1276974   (9.1%) 
   30    5740  (35.0%)      1631570316  (16.3%)         1901404  (13.6%) 
   40    7487  (45.7%)      2172838616  (21.7%)         2525834  (18.0%) 
   50    9234  (56.4%)      2714106916  (27.1%)         3150264  (22.5%) 
   60   10980  (67.0%)      3255375216  (32.6%)         3774694  (27.0%) 
   70   12727  (77.7%)      3796643516  (38.0%)         4399124  (31.4%) 
   80   14474  (88.3%)      4337911816  (43.4%)         5023554  (35.9%) 
   90   16221  (99.0%)      4879180116  (48.8%)         5647984  (40.3%) 
  100   17968 (109.7%)      5420448416  (54.2%)         6272414  (44.8%) 
  110   19715 (120.3%)      5961716716  (59.6%)         6896844  (49.3%) 
  120   21461 (131.0%)      6502985016  (65.0%)         7521274  (53.7%) 
  130   23208 (141.7%)      7044253316  (70.4%)         8145704  (58.2%) 
  140   24955 (152.3%)      7585521616  (75.9%)         8770134  (62.6%) 
  150   26702 (163.0%)      8126789916  (81.3%)         9394564  (67.1%) 

brainrake pushed a commit to mlabs-haskell/plutus that referenced this pull request Dec 8, 2022
* WIP

* Measuring ed25519 signature verification throughput

* Address PR comments

* More tidying up

* Add test for Haskell version

* Defeat short-circuiting in &&

* Restore editorconfig-checker-disable-file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants