func rootKeyAgreementSender( senderHeaderPub *[32]byte, senderIdentity, recipientIdentity string, senderSession, senderID, recipientKI, recipientID *uid.KeyEntry, previousRootKeyHash *[64]byte, numOfKeys uint64, keyStore session.Store, ) error { senderIdentityPub := senderID.PublicKey32() senderIdentityPriv := senderID.PrivateKey32() senderSessionPub := senderSession.PublicKey32() senderSessionPriv := senderSession.PrivateKey32() recipientIdentityPub := recipientID.PublicKey32() recipientKeyInitPub := recipientKI.PublicKey32() log.Debugf("senderIdentityPub: %s", base64.Encode(senderIdentityPub[:])) log.Debugf("senderSessionPub: %s", base64.Encode(senderSessionPub[:])) log.Debugf("recipientIdentityPub: %s", base64.Encode(recipientIdentityPub[:])) log.Debugf("recipientKeyInitPub: %s", base64.Encode(recipientKeyInitPub[:])) // check keys to prevent reflection attacks and replays err := checkKeys(senderHeaderPub, senderIdentityPub, senderSessionPub, recipientIdentityPub, recipientKeyInitPub) if err != nil { return err } // compute t1 t1, err := cipher.ECDH(senderIdentityPriv, recipientKeyInitPub, senderIdentityPub) if err != nil { return err } // compute t2 t2, err := cipher.ECDH(senderSessionPriv, recipientKeyInitPub, senderSessionPub) if err != nil { return err } // compute t3 t3, err := cipher.ECDH(senderSessionPriv, recipientIdentityPub, senderSessionPub) if err != nil { return err } // derive root key rootKey, err := deriveRootKey(t1, t2, t3, previousRootKeyHash) if err != nil { return err } // generate message keys err = generateMessageKeys(senderIdentity, recipientIdentity, senderID.HASH, recipientID.HASH, rootKey, false, senderSessionPub, recipientKeyInitPub, numOfKeys, keyStore) if err != nil { return err } return nil }