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

Add xcryptobackendgen tool, x/crypto fork #92

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

dagood
Copy link
Member

@dagood dagood commented Sep 15, 2023

Draft of the xcryptobackendgen tool and x/crypto fork with some SHA3 implemented and some temporary debugging prints. There's also some cleanup to the tool code I know I want to do. For this draft, my goal is to poke at the concept/workflow of patching a fork in go-infra and using a tool to generate the copy that sits in GOROOT/ms_mod.

// random or pseudorandom cryptographically strong key. See RFC 5869, Section
// 3.3. Most common scenarios will want to use New instead.
func Expand(hash func() hash.Hash, pseudorandomKey, info []byte) io.Reader {
+ if backend.Enabled && backend.SupportsHKDF() {
Copy link
Member Author

Choose a reason for hiding this comment

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

TODO: Handle MD5? Used in benchmarks, causes a panic.

On the note of benchmarks, this is what I get for hkdf as-is, ignoring md5:

goos: linux
goarch: amd64
pkg: golang.org/x/crypto/hkdf
cpu: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
                     │ nobackend.txt │               openssl.txt                │
                     │    sec/op     │     sec/op      vs base                  │
20ByteSHA1Single-8      2.558µ ± 16%     20.715µ ± 4%    +709.79% (p=0.000 n=8)
32ByteSHA256Single-8    3.136µ ± 12%     22.067µ ± 6%    +603.67% (p=0.000 n=8)
64ByteSHA512Single-8    5.144µ ± 30%     23.604µ ± 5%    +358.90% (p=0.000 n=8)
8ByteSHA1Stream-8       152.5n ±  2%    42068.0n ± 7%  +27485.57% (p=0.000 n=8)
20ByteSHA1Stream-8      359.9n ±  3%    41875.0n ± 5%  +11535.18% (p=0.000 n=8)
8ByteSHA256Stream-8     129.5n ±  3%    61891.5n ± 7%  +47674.22% (p=0.000 n=8)
32ByteSHA256Stream-8    479.4n ±  2%    62910.0n ± 5%  +13022.65% (p=0.000 n=8)
8ByteSHA512Stream-8     89.56n ±  2%   86508.00n ± 7%  +96497.62% (p=0.000 n=8)
64ByteSHA512Stream-8    629.7n ±  2%    88247.5n ± 6%  +13914.21% (p=0.000 n=8)
geomean                 584.2n            43.56µ        +7356.21%

                     │  nobackend.txt   │             openssl.txt              │
                     │       B/s        │      B/s       vs base               │
20ByteSHA1Single-8       7636.7Ki ± 13%   942.4Ki ±  4%  -87.66% (p=0.000 n=8)
32ByteSHA256Single-8      9.732Mi ± 17%   1.383Mi ±  7%  -85.79% (p=0.000 n=8)
64ByteSHA512Single-8     11.873Mi ± 22%   2.589Mi ±  4%  -78.19% (p=0.000 n=8)
8ByteSHA1Stream-8       51225.6Ki ±  4%   185.5Ki ±  5%  -99.64% (p=0.000 n=8)
20ByteSHA1Stream-8      54267.6Ki ±  5%   468.8Ki ±  8%  -99.14% (p=0.000 n=8)
8ByteSHA256Stream-8     60312.5Ki ±  5%   127.0Ki ± 15%  -99.79% (p=0.000 n=8)
32ByteSHA256Stream-8    65185.5Ki ±  3%   498.0Ki ±  4%  -99.24% (p=0.000 n=8)
8ByteSHA512Stream-8    87241.21Ki ±  3%   87.89Ki ± 11%  -99.90% (p=0.000 n=8)
64ByteSHA512Stream-8    99277.3Ki ±  4%   708.0Ki ±  8%  -99.29% (p=0.000 n=8)
geomean                   34.58Mi         474.1Ki        -98.66%

@dagood
Copy link
Member Author

dagood commented Oct 17, 2023

We discussed this in our sync meeting--the AST code is complicated, and we could actually go after this quite differently. Instead of trying to parse the backend Go source with various logic to figure out which bits are important and transform the code into proxy code, we can change the source of truth. We can use some Go code and/or JSON to define the backend functionality and use that to generate the backend Go source and these x/crypto proxy backends. We already use a generator to write out the compile-time error Go code in microsoft/go, and this could be combined to also simplify that code.

This would also make it easier to add new functionality to the backends, a process that has been done manually so far. Generating the Go code based on a shared source of truth should make it easier to be sure the set of functions matches between backends, harder to make copy-paste errors, and (probably) make it easier to deal with merge conflicts because the context is concentrated in one file.


Something that came to mind: a reason I was going with the parsing approach is to share tooling with other Go forks with minimal backend edits. The source of truth currently is the Go code, and in theory the x/crypto fork could be plugged in without changing it. However, I don't think this idea holds up:

  • With functions potentially having different names or different syntax being used in each fork's backends, the edge cases would pile up (even higher than they are now), and they might even fundamentally conflict.
  • A tool could always be written to parse Go code and write intermediate temporary JSON data, if there are cases where this has enough value.

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.

1 participant