ceremonyclient/node/crypto/x3dh.go
2023-08-20 23:07:43 -05:00

86 lines
2.3 KiB
Go

package crypto
import (
"crypto/sha512"
"golang.org/x/crypto/hkdf"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves"
)
var domainSeparators = map[string][]byte{
curves.ED448().Name: {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF,
},
}
func SenderX3DH(
sendingIdentityPrivateKey curves.Scalar,
sendingEphemeralPrivateKey curves.Scalar,
receivingIdentityKey curves.Point,
receivingSignedPreKey curves.Point,
sessionKeyLength uint8,
) []byte {
xdh1 := receivingSignedPreKey.Mul(
sendingIdentityPrivateKey,
).ToAffineCompressed()
xdh2 := receivingIdentityKey.Mul(
sendingEphemeralPrivateKey,
).ToAffineCompressed()
xdh3 := receivingSignedPreKey.Mul(
sendingEphemeralPrivateKey,
).ToAffineCompressed()
salt := make([]byte, sessionKeyLength)
x3dh := hkdf.New(sha512.New, append(
append(
append(
append([]byte{}, domainSeparators[receivingIdentityKey.CurveName()]...),
xdh1[:]...),
xdh2[:]...),
xdh3[:]...), salt, []byte("quilibrium-x3dh"))
sessionKey := make([]byte, sessionKeyLength)
if _, err := x3dh.Read(sessionKey[:]); err != nil {
return nil
}
return sessionKey
}
func ReceiverX3DH(
sendingIdentityPrivateKey curves.Scalar,
sendingSignedPrePrivateKey curves.Scalar,
receivingIdentityKey curves.Point,
receivingEphemeralKey curves.Point,
sessionKeyLength uint8,
) []byte {
xdh1 := receivingIdentityKey.Mul(
sendingSignedPrePrivateKey,
).ToAffineCompressed()
xdh2 := receivingEphemeralKey.Mul(
sendingIdentityPrivateKey,
).ToAffineCompressed()
xdh3 := receivingEphemeralKey.Mul(
sendingSignedPrePrivateKey,
).ToAffineCompressed()
salt := make([]byte, sessionKeyLength)
x3dh := hkdf.New(sha512.New, append(
append(
append(
append([]byte{}, domainSeparators[receivingIdentityKey.CurveName()]...),
xdh1[:]...),
xdh2[:]...),
xdh3[:]...), salt, []byte("quilibrium-x3dh"))
sessionKey := make([]byte, sessionKeyLength)
if _, err := x3dh.Read(sessionKey[:]); err != nil {
return nil
}
return sessionKey
}