-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Reviewing the Go implementation #93
Comments
/cc @FiloSottile |
In the case of returning unexported types, you can also create a public interface with no methods, or export the type while leaving all the methods and members unexported. Pure static methods can just be exported methods in a package. If there's no state, there's no reason to tie them to an object. For example, in the case of the cleartext keyset functions, you can just have the |
Thanks for the suggestion @dgryski.
It looks like I can get rid of these types. https://github.com/google/tink/blob/master/go/aead/aead_config.go just consists of static methods and (in the near future) constants, so it looks like I can merge them to the aead package.
These methods need to stay in the same package as keyset_handle.go. Otherwise they cannot call the newKeysetHandle method. We want to restrict access to that method because we want to control who can read cleartext keysets (which is a bad practice). I think I have two choices: 1/ Moving both keyset_handle.go and cleartext_keyset_handle.go to tink/keyset_handle package, or 2/ Keep them in tink. I prefer 1/. |
How long would a full refactor of the golang methods take? From what I can tell, most of the functions are becoming static context? |
Hi Thai, if you're not working with anyone on this already then perhaps I could help. Thank you for having Go version :)
I think that it makes sense. I'd say that if most common use-cases are easy to get right and less common use-cases are supported then the API makes sense. I don't know what those use-cases are though. It would really be very helpful if you provided examples of what you consider the most common intended usage of this API. We could decide what Go code we'd want to write for them and then derive the API from that. We should also include those examples in the documentation (you'd rather have people copy-paste your examples than code written by others and we both know that something will get copy-pasted). I've seen your Java examples. It's unclear to me how representative of actual usage those are. I'd typically focus on the high-level API first but since I'm not sure how far from Java we could go and what problem we're solving (code examples), I also listed below a few easy-to-fix things that I noticed. That is, less API design, more Go readability. Protos vs Go types:
Keyset also looks like something that could get its own package. It looks like there are a lot of keyset operations. You could have keyset.{Decrypt,Encrypt,Encrypted,ToProto,FromProto}. In general, it might be good to hide protos from users. Naming:
With:
In general, put enough context in variable names that it's clear what they mean. Don't include context that's obvious from the code around.
Line breaks:
would be better as
Setters/Getters:
It would be better to just export keyTemplate. Comments:
All exported names should be documented, but this name is unexported and this comment could be dropped.
godoc doesn't recognize {@code ...} syntax and you end up with:
I still don't know what this registry is and why I should care (the "registry" type is unexported and godoc doesn't show its documentation). Function signatures: Consider:
Internal packages: Interfaces: In Go, you'd typically define an interface when:
The purpose of the "KeyManager" interfaces isn't clear to me. It's large so it's hard to implement and most callers won't care about all methods. It's never used except to assert that types implement it. I suggest dropping it. If someone needs to use two different KeyManagers then they can define their own interface. Most likely they'll use a subset of methods. I don't understand the Aead interface either. It seems that there's only one implementation and it's unclear that users are expected to provide their own. Same for tink.Mac, PublicKeySign,PublicKeyManager,PublicKeyVerify. As to returning unexported types. We could talk about that but it really depends on what kind of help you expect here. I think that this problem arises because the API is shaped after the Java API. Ideally we would have an API that returns exported structs instead. |
1/ Replacing tink.Registry().Blah() with tink.Blah(). 2/ Updating the APIs and code structure, following latest Java APIs. The Golang implementation was developed following Java 1.0.0, but many things have changed since then. Next: * Adding missing APIs such as KeysetReader, KeysetWriter. * Removing tink.CleartextKeysetHandle(). * Adding RegistryConfig. * Adding missing primitives such as envelope encryption, hybrid encryption, etc. PiperOrigin-RevId: 196266656 GitOrigin-RevId: f4fe243c4501017922eaed1b464da70d3936c7ac
Thanks so much for your comments! I'll address the readability issues first, then I'll schedule a meeting to discuss the API design. I made the changes in 92c541b several days ago, before I saw your comment today. In that change, I made most of the functions static, i.e., replacing tink.Registry().blah() with tink.blah(). BTW the registry is just a map of key types to their implementations; we need it because we want to make Tink modular, i.e., users can include only key types that they need or they can add their own key types. |
sounds good |
…e issues. This is following the suggestions in #93. PiperOrigin-RevId: 214631857 GitOrigin-RevId: 026bf50e08afd8ccf00f2fcaffa5b9d0f736eedb
This is following the suggestions in #93. PiperOrigin-RevId: 214831222 GitOrigin-RevId: 75e6c903d4eb801e6726c30fd51542f2116df684
This is a rather large change because it touches public APIs, so I want to include all possible changes to make it easier for our current users to migrate in one go. Notable changes: * Add a mechanism that allows to restrict the visibility of functions that accept cleartext keys. * s/Aead/AEAD/, s/Mac/MAC/, s/ComputeMac/ComputeMAC/, s/VerifyMac/VerifyMAC/, s/PublicKeySign/Signer/, s/PublicKeyVerify/Verifier/ * s/aead.GetPrimitive/aead.New/, etc. * s/aead.RegisterStandardKeyTypes/aead.Register/, etc. PiperOrigin-RevId: 215424138 GitOrigin-RevId: 3e9452ec61d04294ab0afdc9c395fe320cefa6a7
Follows API cleanup in Tink per tink-crypto/tink#93. It seems like Tink removed the capability to read/write encrypted keysets, so I've had to use insecure.KeysetHandle in a few places.
* Merge Tink API changes Follows API cleanup in Tink per tink-crypto/tink#93. It seems like Tink removed the capability to read/write encrypted keysets, so I've had to use insecure.KeysetHandle in a few places.
Ref: #93. PiperOrigin-RevId: 215967965 GitOrigin-RevId: 4eeba51b1ae8d4b71e0512c385d57f2e317479ba
Follows google/tink# Part of tink-crypto/tink#93
What's left to do for this issue? Can this be closed? Are there substantial missing components from the Go implementation that we're waiting on? If so, should they have their own tracking issues? |
This is almost done. You can see the new structure at https://godoc.org/github.com/google/tink/go. We're on track to include Go as part of 1.3.0 release. |
Golang support was included in 1.3.0 RC1. If you have some free time, please play with it (instruction is https://github.com/google/tink/blob/master/docs/GOLANG-HOWTO.md) and file bugs if you encounter anything undesirable. This historical bug can now be closed. Thanks everybody for your insights! |
We want to release a Go implementation in 1.2.0. Aside from missing features that we're working hard to implement, there's also a couple of things in the code base that I'm not sure what we should do. I want to use this ticket to get some help or comments from the Go community.
First thing first, does the Go API make sense?
We copied the Java API, so I'm not entirely sure that it fits Go's style and philosophy. For example, our Lint tool warns us that https://github.com/google/tink/blob/master/go/aead/aead_config.go#L39 and several other places return unexported type *aead.config, which can be annoying to use. Is this problem important and we should fix it?
Secondly, I don't know any good way to implement classes consisting of pure static methods like CleartextKeysetHandle. To call a function in this class Go users have to initialize an object, while in Java users can just call the function directly (e.g., CleartextKeysetHandle().blah() versus CleartextKeysetHandle.blah()).
Aside from these immediate issues, we'd love to hear any feedback from the Go community on the API, the structure of the code base, coding style, features, etc.
Thanks!
@gdbelvin @dgryski
The text was updated successfully, but these errors were encountered: