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.schu...@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+unsubscr...@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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEZ4qmHh%3Ds4Bs6oDZDB3%2BYYrMSNeuVbcBpD-8%2BKH20Q3A%40mail.gmail.com.

Reply via email to