types/key: add naclbox shared key wrapper type + Seal method
So the control plane can stop doing precomputations on each naclbox message. Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
6f5096fa61
commit
cfdb862673
|
@ -105,6 +105,33 @@ func (k MachinePrivate) SealTo(p MachinePublic, cleartext []byte) (ciphertext []
|
|||
return box.Seal(nonce[:], cleartext, &nonce, &p.k, &k.k)
|
||||
}
|
||||
|
||||
// SharedKey returns the precomputed Nacl box shared key between k and p.
|
||||
func (k MachinePrivate) SharedKey(p MachinePublic) MachinePrecomputedSharedKey {
|
||||
var shared MachinePrecomputedSharedKey
|
||||
box.Precompute(&shared.k, &p.k, &k.k)
|
||||
return shared
|
||||
}
|
||||
|
||||
// MachinePrecomputedSharedKey is a precomputed shared NaCl box shared key.
|
||||
type MachinePrecomputedSharedKey struct {
|
||||
k [32]byte
|
||||
}
|
||||
|
||||
// Seal wraps cleartext into a NaCl box (see
|
||||
// golang.org/x/crypto/nacl) using the shared key k as generated
|
||||
// by MachinePrivate.SharedKey.
|
||||
//
|
||||
// The returned ciphertext is a 24-byte nonce concatenated with the
|
||||
// box value.
|
||||
func (k MachinePrecomputedSharedKey) Seal(cleartext []byte) (ciphertext []byte) {
|
||||
if k == (MachinePrecomputedSharedKey{}) {
|
||||
panic("can't seal with zero keys")
|
||||
}
|
||||
var nonce [24]byte
|
||||
rand(nonce[:])
|
||||
return box.SealAfterPrecomputation(nonce[:], cleartext, &nonce, &k.k)
|
||||
}
|
||||
|
||||
// OpenFrom opens the NaCl box ciphertext, which must be a value
|
||||
// created by SealTo, and returns the inner cleartext if ciphertext is
|
||||
// a valid box from p to k.
|
||||
|
|
|
@ -90,3 +90,23 @@ func TestMachineSerialization(t *testing.T) {
|
|||
t.Error("json serialization doesn't roundtrip")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSealViaSharedKey(t *testing.T) {
|
||||
// encrypt a message from a to b
|
||||
a := NewMachine()
|
||||
b := NewMachine()
|
||||
apub, bpub := a.Public(), b.Public()
|
||||
|
||||
shared := a.SharedKey(bpub)
|
||||
|
||||
const clear = "the eagle flies at midnight"
|
||||
enc := shared.Seal([]byte(clear))
|
||||
|
||||
back, ok := b.OpenFrom(apub, enc)
|
||||
if !ok {
|
||||
t.Fatal("failed to decrypt")
|
||||
}
|
||||
if string(back) != clear {
|
||||
t.Errorf("got %q; want cleartext %q", back, clear)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue