36 lines
1.3 KiB
Go
36 lines
1.3 KiB
Go
package primitives
|
|
|
|
import (
|
|
"golang.org/x/crypto/ed25519"
|
|
"golang.org/x/crypto/sha3"
|
|
)
|
|
|
|
// Perform3DH encapsulates a triple-diffie-hellman key exchange.
|
|
// In this exchange Alice and Bob both hold longterm identity keypairs
|
|
// Both Alice and Bob generate an additional ephemeral key pair:
|
|
// Three Diffie Hellman exchanges are then performed:
|
|
// Alice Long Term <-> Bob Ephemeral
|
|
// Alice Ephemeral <-> Bob Long Term
|
|
// Alice Ephemeral <-> Bob Ephemeral
|
|
//
|
|
// Through this, a unique session key is derived. The exchange is offline-deniable (in the context of Tapir and Onion Service)
|
|
func Perform3DH(longtermIdentity *Identity, ephemeralIdentity *Identity, remoteLongTermPublicKey ed25519.PublicKey, remoteEphemeralPublicKey ed25519.PublicKey, outbound bool) [32]byte {
|
|
// 3DH Handshake
|
|
l2e := longtermIdentity.EDH(remoteEphemeralPublicKey)
|
|
e2l := ephemeralIdentity.EDH(remoteLongTermPublicKey)
|
|
e2e := ephemeralIdentity.EDH(remoteEphemeralPublicKey)
|
|
|
|
// We need to define an order for the result concatenation so that both sides derive the same key.
|
|
var result [96]byte
|
|
if outbound {
|
|
copy(result[0:32], l2e)
|
|
copy(result[32:64], e2l)
|
|
copy(result[64:96], e2e)
|
|
} else {
|
|
copy(result[0:32], e2l)
|
|
copy(result[32:64], l2e)
|
|
copy(result[64:96], e2e)
|
|
}
|
|
return sha3.Sum256(result[:])
|
|
}
|