On Mon, Oct 9, 2023, 1:59 PM Dean Schulze <dean.w.schu...@gmail.com> wrote:
> That is mixing concerns (low cohesion), though. At the very least they > need to explain that in the docs. Otherwise that first parameter makes no > sense. > This is a common design pattern in Go. We shouldn't expect that every function that uses it has to explain the idea. We should figure out a way for people to discover and understand it. Ian On Monday, October 9, 2023 at 2:51:11 PM UTC-6 David Anderson wrote: > >> The first parameter lets you avoid an allocation. If you're constructing >> a packet that consists of ciphertext surrounded by some framing, you can >> make([]byte, 0, lengthOfPacket) to preallocate the necessary amount of >> storage upfront. Then, calls to secretbox don't allocate. >> >> If you don't need that behavior, you can pass in a nil as the first >> parameter to get a fresh slice allocated for you by the append(), but in >> hot codepaths involving cryptography, being able to preallocate and reuse >> storage (e.g. via sync.Pool) can give you significant reduction in GC >> pressure. >> >> - Dave >> >> On Mon, Oct 9, 2023, at 08:43, Dean Schulze wrote: >> >> So why even bother with the first parameter then? That looks like a >> badly designed method signature. >> >> On Monday, October 9, 2023 at 8:12:33 AM UTC-6 Axel Wagner wrote: >> >> I get the impression that the thing you are missing is that appending to >> a slice does not modify it. That is, `append(s, x...)` modifies neither the >> length, nor the content of `s`, you have to type `x = append(s, x...)`. >> `Seal` (and `Open`) work exactly the same. They append to the `out` >> parameter - and to enable you to get at the slice, they return it. >> >> The docs could be slightly more clear, by explicitly stating that they >> return the appended-to slice.0 >> >> >> On Mon, Oct 9, 2023 at 3:46 PM Dean Schulze <dean.w....@gmail.com> wrote: >> >> If the docs are correct, how do you append to nil? That's what the docs >> say. Take a look at them. >> >> Your code example shows the first parameter to Seal() can be nil. So >> what does that parameter do? How do you append to it? >> On Sunday, October 8, 2023 at 11:19:13 PM UTC-6 Axel Wagner wrote: >> >> For what it's worth, here is an example that demonstrates a typical >> encryption/decryption roundtrip, perhaps more clearly: >> https://go.dev/play/p/ZZry8IgTJQ_- >> The `out` parameter can be used to make this more efficient by using >> pre-allocated buffers (depending on use case) and there are cases where you >> don't have to send the nonce, because you can derive them from common data, >> which is why both of these parameters are there. But in the most common >> usage, you'd do what this example does. >> >> The example code from the docs tries to be a little bit more efficient >> and packs the `Box` struct into a single byte, perhaps at the cost of >> understandability. >> >> On Mon, Oct 9, 2023 at 7:06 AM Axel Wagner <axel.wa...@googlemail.com> >> wrote: >> >> oh I forgot to emphasize: I don't believe the output is *really* >> `<encryptedMessage><hash>`. That is, I don't believe you can really treat >> the first N bytes as the encrypted text and decrypt it (say, if you didn't >> care about the authentication). It's just that you ultimately need to add >> 16 bytes of extra information to carry that authentication tag, which is >> why the box needs to be 16 bytes longer than the message. In reality, the >> two are probably cleverly mixed - I'm not a cryptographer. >> I just wanted to demonstrate where all the information ultimately goes. >> >> On Mon, Oct 9, 2023 at 7:03 AM Axel Wagner <axel.wa...@googlemail.com> >> wrote: >> >> I don't really understand your issue. You call >> encrypted := secretbox.Seal(nonce[:], []byte(s), &nonce, &secretKey) >> That means you pass `nonce[:]` as the `out` argument, `s` as the >> `message` argument, and the nonce and key and assign the result to >> `encrypted`. >> According to the docs of `secretbox`, `Seal` will `append` the encrypted >> message to `nonce[:]` and that encrypted message will be 16 bytes longer >> than the message, which is 11 bytes long. Appending 37 (16+11) bytes to a >> 24 byte nonce gives you 51 bytes, which is what you observe as the length >> of `encrypted`. >> The length of `nonce` doesn't change (it's an array, after all) - but >> passing `append` to a slice does not change the length of the slice, it >> just returns a new slice, so that seems expected. >> >> So, from what I can tell, the code does exactly what the docs say it >> should do. >> >> > In their example code the out parameter is nil. So what does it do? >> >> Appending to `nil` allocates a new slice. The point of still accepting an >> `out` parameter is that you can potentially prevent an allocation by >> passing in a slice with 0 length and extra capacity (which can then be >> allocated on the stack, or which is from a `sync.Pool`). If you don't need >> that, passing in `nil` seems fine. >> >> > The second argument is encrypted[len(nonce):] which includes the >> Overhead at the start of the []byte. Apparently that Overhead is important. >> >> Yes, the Overhead is important. It is used to authenticate the message. >> You can imagine the process of `Seal` as "encrypt the message and attach a >> hash". The hash is the Overhead. The process also needs a random `nonce`, >> that both the sender and the receiver need to know. That's why the example >> code sends it along with the message (it doesn't have to be secret). So >> that `Seal` call does, effectively (again, for illustrative purposes): >> encrypted := append(append(nonce, <encryptedMessage>), <hash>) >> As `nonce` is an array, this allocates a new backing array for the >> returned slice, which ends up filled with >> <nonce><encryptedMessage><hash> >> >> The `Open` call then retrieves the `nonce` from the first 24 bytes (by >> copying it into `decryptNonce`) and passes the `<encryptedMessage><hash>` >> slice as the `box` argument. Which decrypts the message, authenticates the >> hash and appends the decrypted message to `out` (which is `nil` in the >> example code). >> >> So, the docs are correct. And it seems to me, the code works as expected. >> I'm not sure where the misunderstanding is. >> >> >> -- >> >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/3d7d75e5-d79a-4f81-978d-cb6feb7b12efn%40googlegroups.com >> <https://groups.google.com/d/msgid/golang-nuts/3d7d75e5-d79a-4f81-978d-cb6feb7b12efn%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts...@googlegroups.com. >> >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/0fc63e62-0911-4ad1-b209-570c063a61c3n%40googlegroups.com >> <https://groups.google.com/d/msgid/golang-nuts/0fc63e62-0911-4ad1-b209-570c063a61c3n%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> >> >> -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/7542b613-d9bf-43aa-ad98-877434350de8n%40googlegroups.com > <https://groups.google.com/d/msgid/golang-nuts/7542b613-d9bf-43aa-ad98-877434350de8n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcXByqe9UpOstQD4%2BnEFSJen7dPMCPuH8fz412%3DsqvwokQ%40mail.gmail.com.