Open jbenet opened 7 years ago
This is outdated. See: https://github.com/ipfs/notes/issues/177#issuecomment-255588927
My suggestion: It is constriction quite similar to cjdns's:
SS = <shared secret>
N = make([]byte, 24) // 192 bits
copy(N[8:], randomNonce(16))
conn.Write(N[8:])
i = int64(0)
for {
binary.BigEndian.PutUint64(N, i)
data := getOutgoingData()
salsa20.XORKeyStream(data, data, N, SS)
conn.Write(data)
i++
}
why not use varints?
Also, what is the necessity for having the counter? If its an xor'ed keystream it has to be ordered anyways.
why not use varints?
Where you want to put varints, the base of the nonce is sent once per connection. If you mean PutUint64, then I always need 8 bytes.
Also, what is the necessity for having the counter?
Salsa20 is stateless, it can't be resumed (it has internal counter but it isn't exposed), that is why one uses counter as part of the nonce.
The schema had to change a bit as I didn't took into account read re-fragmentation of TCP buffers and no maximum frame length on this level (nor I wanted to introduce one).
Right now it is:
SS = <shared secret>
N = randomNonce(24) // 192bits
conn.Write(N)
S20 = salsa20.NewStream(SS, N)
for {
data := getOutgoingData()
S20.XORKeyStream(data, data)
conn.Write(data)
}
Same benefits apply, most importatnly, there is no need for rekeying as it is with AES. Salsa20 stream is 2^70
bytes long as for the 64bit internal counter, versus AES stream modes using 32bit counters.
The performance of salsa20 is double of AES even on modern architectures with dedicated AES instructions (tested on i7-6800k) and it keeps being double on 32bit ARM. The difference will be even higher one AArch64 becomes more popular.
@Kubuxu's last suggestion is fine, you don't need framing or counters, because you have integrity from the next layer. However, you could just encrypt the handshake like this, but not the rest of the session and you'd still preserve your desired properties without another layer of encryption, but then you basically have a integrated design, but this clearly simple to implement as a layer.
Caveats:
Construction 1:
Though really:
Construction 2:
Construction 3: