skip outgoing messages for decryption

This commit is contained in:
kaichaosun 2025-11-20 15:06:09 +08:00
parent ba124a3739
commit 6dff127cab
No known key found for this signature in database
GPG Key ID: 223E0F992F4F03BF
4 changed files with 40 additions and 5 deletions

View File

@ -31,7 +31,10 @@ proc main() {.async.} =
let sIdent = Identity(name: "saro", privateKey: sKey)
# Create Clients
info "create saro client"
var saro = newClient(cfg_saro, sIdent)
info "create raya client"
var raya = newClient(cfg_raya, Identity(name: "raya", privateKey: rKey))
var ri = 0

View File

@ -72,8 +72,16 @@ proc calcMsgId(self: PrivateV1, msgBytes: seq[byte]): string =
proc encrypt*(convo: PrivateV1, plaintext: var seq[byte]): EncryptedPayload =
info "encrypt metadata"
info "Doubleratchet DH Self: ", dhSelf = convo.doubleratchet.dhSelf
info "dh self public:" , dhSelfPub = convo.doubleratchet.dhSelf.public
info "dhRemote: ", dhRemote = convo.doubleratchet.dhRemote
let (header, ciphertext) = convo.doubleratchet.encrypt(plaintext) #TODO: Associated Data
info "encrypt done"
info "header dh public: ", dhPub = header.dhPublic
result = EncryptedPayload(doubleratchet: proto_types.DoubleRatchet(
dh: toSeq(header.dhPublic),
msgNum: header.msgNumber,
@ -93,6 +101,16 @@ proc decrypt*(convo: PrivateV1, enc: EncryptedPayload): Result[seq[byte], ChatEr
prevChainLen: dr.prevChainLen
)
copyMem(addr header.dhPublic[0], unsafeAddr dr.dh[0], dr.dh.len) # TODO: Avoid this copy
info "decrypt metadata"
info "header dh public: ", dhPub = header.dhPublic
info "Doubleratchet DH Remote: ", dhRemote = convo.doubleratchet.dhRemote
info "dh self:", dhSelf = convo.doubleratchet.dhSelf
info "dh self public:" , dhSelfPub = convo.doubleratchet.dhSelf.public
if convo.doubleratchet.dhSelf.public == header.dhPublic:
info "outgoing message, no need to decrypt"
return err(ChatError(code: errDecryptOutgoing, context: "Attempted to decrypt outgoing message"))
convo.doubleratchet.decrypt(header, dr.ciphertext, @[]).mapErr(proc(e: NaxolotlError): ChatError = ChatError(code: errWrapped, context: repr(e) ))

View File

@ -8,6 +8,7 @@ type
ErrorCode* = enum
errTypeError
errWrapped
errDecryptOutgoing
proc `$`*(x: ChatError): string =

View File

@ -16,8 +16,8 @@ const maxSkip = 10
type Doubleratchet* = object
dhSelf: PrivateKey
dhRemote: PublicKey
dhSelf*: PrivateKey
dhRemote*: PublicKey
rootKey: RootKey
chainKeySend: ChainKey
@ -73,8 +73,9 @@ func kdfChain(self: Doubleratchet, chainKey: ChainKey): (MessageKey, ChainKey) =
return(msgKey, chainKey)
func dhRatchetSend(self: var Doubleratchet) =
proc dhRatchetSend(self: var Doubleratchet) =
# Perform DH Ratchet step when receiving a new peer key.
info "dhRatchetSend DH Self: ", dhSelf = self.dhSelf
let dhOutput : DhDerivedKey = dhExchange(self.dhSelf, self.dhRemote).get()
let (newRootKey, newChainKeySend) = kdfRoot(self, self.rootKey, dhOutput)
self.rootKey = newRootKey
@ -82,6 +83,8 @@ func dhRatchetSend(self: var Doubleratchet) =
self.msgCountSend = 0
proc dhRatchetRecv(self: var Doubleratchet, remotePublickey: PublicKey ) =
info "dh ratchet happens"
info "dhRatchetRecv DH Remote: ", dhRemote = remotePublickey
self.prevChainLen = self.msgCountSend
self.msgCountSend = 0
self.msgCountRecv = 0
@ -96,7 +99,7 @@ proc dhRatchetRecv(self: var Doubleratchet, remotePublickey: PublicKey ) =
self.dhSelf = generateKeypair().get()[0]
let dhOutputPost = self.dhSelf.dhExchange(self.dhRemote).get()
(self.rootKey, self.chainKeyRecv) = kdfRoot(self, self.rootKey, dhOutputPost)
(self.rootKey, self.chainKeySend) = kdfRoot(self, self.rootKey, dhOutputPost)
proc skipMessageKeys(self: var Doubleratchet, until: MsgCount): Result[(), string] =
@ -138,9 +141,15 @@ proc encrypt(self: var Doubleratchet, plaintext: var seq[byte], associatedData:
proc decrypt*(self: var Doubleratchet, header: DrHeader, ciphertext: CipherText, associatedData: openArray[byte] ) : Result[seq[byte], NaxolotlError] =
info "double ratchet decrypt", header = $header
info "dhRemote: ", dhRemote = self.dhRemote
info "dhSelf: ", dhSelf = self.dhSelf
info "dhSelf public: ", dhSelf = self.dhSelf.public
let peerPublic = header.dhPublic
info "peerPublic: ", peerPublic = peerPublic
var msgKey : MessageKey
# Check Skipped Keys
@ -176,8 +185,12 @@ proc encrypt*(self: var Doubleratchet, plaintext: var seq[byte]) : (DrHeader, Ci
encrypt(self, plaintext,@[])
func initDoubleratchet*(sharedSecret: array[32, byte], dhSelf: PrivateKey, dhRemote: PublicKey, isSending: bool = true): Doubleratchet =
proc initDoubleratchet*(sharedSecret: array[32, byte], dhSelf: PrivateKey, dhRemote: PublicKey, isSending: bool = true): Doubleratchet =
info "Initializing Double Ratchet"
info "DH Self: ", dhSelf = dhSelf
info "DH Self public: ", dhSelf = dhSelf.public
info "DH Remote: ", dhRemote = dhRemote
result = Doubleratchet(
dhSelf: dhSelf,
dhRemote: dhRemote,