microsoft / go-crypto-winnative

Go crypto backend for Windows using CNG
MIT License
28 stars 3 forks source link

Reuse backing array when creting BigInts #14

Closed qmuntal closed 2 years ago

qmuntal commented 2 years ago

This PR reduce to the bare minimum the allocations in GenerateKeyRSA and GenerateKeyECDSA by reusing the same backing array when creating each BigInt, instead of allocating a new byte slice each time.

The trick is that BigInt is defined to have the same representation as a CNG big integer, so we can create new BigInts by just slicing the blob returned by BCryptExportKey. Go garbage collector is smart enough to keep the backing array live meanwhile there is a slice referencing it.

These are the allocation improvements:

name                 old allocs/op  new allocs/op  delta
SignECDSA-12             1.00 ± 0%      1.00 ± 0%     ~     (all equal)
VerifyECDSA-12           0.00           0.00          ~     (all equal)
GenerateKeyECDSA-12      4.00 ± 0%      1.00 ± 0%  -75.00%  (p=0.000 n=10+10)
EncryptRSAPKCS1-12       1.00 ± 0%      1.00 ± 0%     ~     (all equal)
GenerateKeyRSA-12        9.00 ± 0%      1.00 ± 0%  -88.89%  (p=0.000 n=10+10)
Hash8Bytes-12            0.00           0.00          ~     (all equal)
SHA256-12                0.00           0.00          ~     (all equal)