Changes

MpOTR/algorithm dump

6,246 bytes added, 9 years ago
/* Common functions used by other procedures in different stages */
===Example of an Algorithm in Wiki===
{{algorithm-begin|name=LargestNumber}}
Input: A list of numbers ''L''.
Output: The largest number in the list ''L''.
 
''largest'' ← null
'''for each''' ''item'' '''in''' "L"', '''do'''
'''if''' ''item'' > ''largest'', '''then'''
''largest'' ← ''item''
'''return''' ''largest''
{{algorithm-end}}
 
===mpOTR algorithms===
====Chatroom setup====
<!--alg_chat_setup-->
{{algorithm-begin|name=Chat Initiator Chatroom Init}} Input: ''<math>newRoomName''</math>, <math>participantNick</math> ''participantNick'global' Global ''<math>myId := 1''</math> Global '''global''' <math>Nick_{myId} := participantNick''</math> Global '''global''' <math>roomName := newRoomName''</math> Global '''global''' <math>x_{myId}, y_{myId} :='' '''Call''' </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Generate Initial Paramters</span>'''(''<math>myId''</math>) Global '''global''' <math>signatureKey_{myId} := (x_{myId},y_{myId})''</math> ''<math>participantList := [Nick_{myId}]''</math> ''<math>ephemeralPublicPointList := [y_{myId}, y_{other}]''</math>
{{algorithm-end}}
{{algorithm-begin|name=Verify Verifier Generate Init Key}}
Input: ''<math>schnorrRandomPoint_{other''}</math>, <math>Hv_{other}</math>, <math>v_{other}</math>, <math>y_{other}</math>, <math>Nick_{other}</math> '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Verify Verifiers</span>'''() Global '''global''' <math>sessionKey := SHA-512Hash(x_{myId}y_{other}, sessionId)''</math> ''<math>toBeSigned := SHA-512Hash(SHA-512Hash(sessionId||SHA-512Hash(y_1, v_1)||SHA-512Hash(y_2,v_2)))''</math> '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Sign Session and Send</span>'''(''<math>toBeSigned''</math>)
{{algorithm-end}}
 
 
 
====Join====
<!--alg_join-->
{{algorithm-begin|name=Join}}
Input: ''<math>newRoomName''</math>, ''<math>Nickname_{myId''}</math>, <math>participantId</math> Global '''global''' <math>myId := participantId''</math> Global '''global''' <math>roomName := newRoomName''</math> ''<math>x_{myId}, y_{myId} := '''''Call''' </math><span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Generate Initial Paramters</span>'''(Participant ID <math>myId</math>) ''myId'global') Global ''<math>signatureKey_{myId} := (x_{myId},y_{myId})''</math> '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Broadcast</span>'''(``":3mpCat:3Join:3''", ''<math>myId''</math>, ''<math>Nickname_{myId''}</math>, <math>y_{myId}</math>) Global '''global''' <math>participantList, ephemeralPublicPointList :='' '''Call''' </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Receive</span>'''() Global ''sessionId := 'global' '''Call''' <math>sessionId := </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Compute Session Id</span>'''(''<math>roomName''</math>, ''<math>participantList''</math>, ''<math>ephemeralPublicPointList''</math>) '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Sign and Send Key Confirmation and Shares</span>'''() '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Wait On Receive</span>'''(``":3mpCat:3KeyConfirmationShare:3''") Global '''global''' <math>keyShareList, keyConfirmationList, signatureList :='' '''Call''' </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Receive</span>'''() '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Verify Key Confirmations and Signatures</span>'''(''<math>keyConfirmationList''</math>, ''<math>signatureList''</math>) '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Update Session Key</span>'''()
{{algorithm-end}}
{{algorithm-begin|name=Receive Session Digest}}
Input: <math>currentSessionHistoryDigest</math> ''currentSessionHistoryDigest'global' Global ''<math>sessionDigest := currentSessionHistoryDigest''</math>
{{algorithm-end}}
====Protocol for other participants already in the chat to accept the newcomer====
 
 
====Protocol for other participants already in the chat to accept the newcomer====
<!--alg_accept-->
{{algorithm-begin|name=Accept}}
Input: <math>newParticipant</math> '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Broadcast</span>'''(``":3mpCat:3Join:3''", ''<math>myId''</math>, ''<math>Nickname_{myId''}</math>, <math>y_{myId}</math>) '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Wait On Receive</span>'''(``":3mpCat:3Join:3''") Global '''global''' <math>nick_{NewParticipant}''</math>, ''<math>ephemeralPublicPoint_{NewParticipant} := '' '''Call''' </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Receive</span>'''() '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Update Lists</span>'''(''<math>nick_{NewParticipant''}</math>, <math>ephemeralPublicPoint_{NewParticipant}</math>) Global ''sessionId := 'global' '''Call''' <math>sessionId := </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Compute Session Id</span>'''(''<math>roomName''</math>, ''<math>participantList''</math>, ''<math>ephemeralPublicPointList''</math>) '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Sign and Send Key Confirmation and Shares</span>'''() '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Wait On Receive</span>'''(``":3mpCat:3KeyConfirmationShare:3''") Global '''global''' <math>keyShareList, keyConfirmationList, signatureList :='' '''Call''' </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Receive</span>'''() '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Verify Key Confirmations and Signatures</span>'''(''<math>keyConfirmationList''</math>, ''<math>signatureList''</math>) '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Update Session Key</span>'''() '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Send</span>'''(''<math>sessionDigest''</math>)
{{algorithm-end}}
<!--alg_farewell-->
{{algorithm-begin|name=Shrink on Leave}}
Input: ''<math>leaverId''</math> Remove ''leaverId'remove' from ''<math>leaverId</math> from <math>participantIdList''</math> Global ''sessionId :='global' '''Call''' <math>sessionId :=</math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Compute Session Id</span>'''() \If{ '''if''' <math>|participantList| > 1</math>''} '''Call, then''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Sign and Send Key Shares</span>'''() '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Wait On Receive</span>'''(``":3mpCat:3KeyShare:3''") '' <math>keyShareList'' </math> := Receive{} <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''CallReceive</span>''' () <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Update Session Key</span>'''(''<math>keyShareList''</math>)
{{algorithm-end}}
{{algorithm-begin|name=Sign and Send Key Shares}}
Input:
Global '''global''' <math>z_{myId -1, myId} := SHA-512Hash(k_{myId,myId-1}, sessionId)''</math> Global '''global''' <math>z_{myId, myId+1} := SHA-512Hash(k_{myId,myId+1}, sessionId)''</math> ''<math>keyShare_{myId} := z_{myId -1, myId} \oplus z_{myId, myId+1}''</math> ''<math>originAuthSignature :='' '''Call''' </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''ED25519Sign</span>'''(''<math>SignatureKey''</math>, ''<math>sessionId'' </math> || ''<math>z_{myId''}</math>) '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Broadcast</span>'''(``":3mpCat:3KeyShare:3''", ''<math>myId''</math>, ''<math>keyShare_{myId''}</math>, <math>originAuthSignature</math>) # we can send this encrypted but leaving person can read it, hence theoretically it is the same as sending it unencrypted.
{{algorithm-end}}
 
====Send====
<!--alg_send-->
{{algorithm-begin|name=Send}}
Input: Message<math>metaMessage</math>, <math>message</math> '' <math>keyShareMessage'' </math> = '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''NewKeyShareMessage</span>'''(MetaMessage<math>metaMessage</math>) '' <math>cryptMessage'' </math> := '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''AES CTR Encrypt</span>'''(''<math>sessionKey''</math>,''<math>message | keyShareMessage''</math>) '' <math>originAuthSignature'' </math> := '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''ED25519Sign</span>'''(''<math>SignatureKey''</math>, ''<math>sessionId'' </math> || ''<math>cryptMetatMessage''</math>) '' <math>sessionDigest'' </math> := '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Compute Session Digest</span>'''(''<math>lastMessage''</math>) '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Broadcast</span>'''(``":3mpCat:3''", ''<math>sessionId''</math>, ''<math>cryptMessage''</math>, ''<math>sessionDigest''</math>, ''<math>originAuthSignature''</math>,``":3''")
{{algorithm-end}}
 
====Recieve====
<!--alg_recv-->
{{algorithm-begin|name=Receive}}
Input: ''<math>sender''</math>, ''<math>encryptedMessage''</math>, ''<math>originAuthSignature''</math>, ''<math>sessionDigest''</math> '' <math>v := '' '''Call''' </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''ED25519VerifySignature</span>'''(''<math>ephemeralPublicKeyList[Sender]''</math>, ''<math>sessionId || encryptedMessage''</math>, ''<math>originAuthSignature''</math>) '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Assert</span>'''(<math>v</math>) or ''v'return') ''Reject <math>message, keyShareMessage :='' '''Call''' </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''AES CTR Decrypt</span>'''(''<math>sessionKey''</math>, ''<math>encryptedMessage''</math>){} '' <math>isMetaMessage = '''''Call''' </math><span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''UpdateNewKeyStatus</span>'''(''<math>keyShareMessage''</math>) '''Call''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Verify Digests</span>'''(''<math>sessionDiges''</math>) '''Returnreturn'''{''<math>isMetaMessage, message''</math>} # isMetaMessage is true if the message is purely meta message and there is nothing to display
{{algorithm-end}}
 
 
\subsection{Common functions}
 
 
====Common functions used by other procedures in different stages====
<!--alg_comm-->
 
 
{{algorithm-begin|name=Generate Initial Paramters}}
Input: ''<math>myId''</math> ''<math>signaturePrivateKey := '' '''Call''' </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''RandomBits</span>'''(256) ''<math>x_{myId} :='' '''Call''' </math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Ed25519 Scalar</span>'''(''<math>signaturePrivateKey''</math>))#{This is both Diffie-Hellman secret and ephemeral signature private key} ''<math>y_{myId} := x_{myId}P''</math> '''Return''return' ''<math>x,y''</math>
{{algorithm-end}}
{{algorithm-begin|name=Verify Key Confirmation and Signatures}}
Input: ''<math>signatureList''</math>, ''<math>keyConfirmationList''</math> '''For for each''' ''<math>participant \in participantList''}</math>, '''do''' \If{'''if''' <math>keyConfirmationList[participant][myId] \neq SHA-512Hash(k_{myId,participant}, U_{myId})</math>''} '''Call, then''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Halt</span>'''() ' \If{''else'Call''' ''if''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''ED25519VerifySignature</span>'''(''<math>ephemeralPublicKeyList[particicpant]''</math>, ''<math>sessionId ||keyShares[myId]''</math>, ''<math>originAuthSignature''</math>)= Fail ' '''Call, then''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Halt</span>'''()
{{algorithm-end}}
{{algorithm-begin|name=Compute Session Id}}
Input: ''<math>participantList''</math>, ''<math>ephemeralPublicPointList''</math> '''Returnreturn''' ''SHA-512<math>Hash(roomeName, zip(participantList, ephemeralPublicPointList))'' </math> # ''<math>zip([a,b],[c,d]):=[(a,c),(b,d)]''</math>
{{algorithm-end}}
{{algorithm-begin|name=Verify Signatures}}
Input: ''<math>longPublicList''</math>,''<math>schnorrRandomPointList''</math>, # standard signature verification
{{algorithm-end}}
{{algorithm-begin|name=Sign and Send Key Confirmation and Share}}
Input: ''<math>schnorrRandomPointList''</math> '''For for each''' ''<math>participant \in participantList''</math>, '''do''' ''<math>k_{myId, participant} := HHash(g^{lp_x_{myId}}LP_{participant} |lp_{myId}y_{participant}^{| x_{myId}y_{participant})'' </math> # Triple DH ''<math>kc_{myId} := kc_{myId} | HHash(k_{myId,participant}, U_{participant})</math> '''global''' <math>z_{myId -1, myId} := Hash(k_{myId,myId-1}, sessionId)</math> '''global''' <math>z_{myId, myId+1} := Hash(k_{myId,myId+1}, sessionId)</math> <math>keyShare_{myId} := z_{myId -1, myId} \oplus z_{myId, myId+1}</math> <math>originAuthSignature :=</math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''ED25519Sign</span>'''(<math>SignatureKey</math>, <math>sessionId</math> || <math>z_{myId}</math>) <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Broadcast</span>'''(":3mpCat:3KeyConfirmationAndShare:3", <math>myId</math>, <math>keyShare_{myId}</math>, <math>originAuthSignature</math>, <math>kc_{myId}</math>){{algorithm-end}}
Global ''z_{myId {algorithm-1, myIdbegin|name=Update Session Key} } Input: <math>keyShareList</math> <math>i := SHA-512(k_{myId</math> '''for each''' <math>{j \in [i,myId...,i+n-1]}</math>, sessionId)'' Global 'do''' <math>z_{myIdj, myIdj+1} := SHA-512(k_z_{myIdj-1,myIdj} \oplus keyShareListe[j+1}]</math> # recovered <math>z_{i-1, sessionId)i}</math> should be equal to its original value '' 'global'keyShare_{myId} '' <math>sessionKey := Hash(z_{myId -j,j+1, myId} | j \oplus z_in [1...n])</math>{myId, myId+1{algorithm-end}}''
''originAuthSignature {{algorithm-begin|name=Sign Params Update Session Key}} Input:<math>toBeSigned</math>, <math>signatureList</math>,<math>keyShareList</math> <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'' '''Call''' '''ED25519SignUpdate Session Key</span>'''(''SignatureKey'', '') <math>toBeSigned := Hash(sessionId'' , || ''z_{myId''Hash(verifierList, ephemeralPublicPointList, keyShareList)))</math> <math>signature_{myId} := </math><span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''CallSign Session and Send</span>''' (<math>toBeSigned</math>) <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''Broadcast</span>'''(``":3mpCat:3KeyConfirmationAndShare3SignedSessionParameters:3''", ''myId'', ''keyShare_<math>signature_{myId''}</math>)
{{algorithm-end}}
{{algorithm-begin|name=Update Session KeyComputeSessionDigest}} Input: ''keyShareList'' ''i := myId''<math>lastMessage</math> '''For for each''' ''{j \<math>message</math> in [i,...,iMessages Received from <math>lastDigestedMessage</math>+n-1]}''}till <math>lastMessage</math>, '''do''' ''z_{j,j+1} <math>sesionDigest := z_{j-1Hass(sessionDigest,j} \oplus keyShareListe[j+1]''message)</math> # recovered <span style="font-family: serif; font-size: larger; font-variant:small-caps;">''z_{i-1,i}'LRU Cache Store Digest</span>' should be equal to its original value Global ''sessionKey := SHA-512(z_{j<math>sessionDigest</math>,j+1} | j \in [1...n]<math>message</math>) '''return''' <math>sessionDigest</math>,<math>lastMessageId</math>
{{algorithm-end}}
{{algorithm-begin|name=Sign Params Update Session KeyNewKeyShareMessage}} Input: ''toBeSigned'', ''signatureList'', ''keyShareList''<math>metaMessage</math> '''Call''' '''Update Session Key'''# Based on metaMessage Determines what type of keyshare needs to be send (Ephemeral point or Group key share) ''toBeSigned := SHA-512(sessionId, ||SHA-512(verifierList, ephemeralPublicPointList, keyShareList)))'' ''signature_{myId} := '''''Call''' '''Sign Session and Send'''(''toBeSigned'') '''Call''' '''Broadcast'''(``:3mpCat:3SignedSessionParameters:3'',''signature_{myId'')returen it.
{{algorithm-end}}
{{algorithm-begin|name=ComputeSessionDigestUpdateNewKeyStatus}} Input: ''lastMessage''<math>keyShareMessage</math>'''For each''' ''message'' in Messages Received from ''lastDigestedMessage''+1 till ''lastMessage'' # Update the table of which participant has sent its new ephemeral point or its new group key share{{algorithm-end}}  {{algorithm-begin|name=Hash}}, '''do''' ''sesionDigest Input:=<math>message</math> '' '''Callreturn''' <span style="font-family: serif; font-size: larger; font-variant:small-caps;">'''SHA-512</span>'''(''sessionDigest'', ''<math>message''</math>) '''Call''' '''LRU Cache Store Digest'''(''sessionDigest'', ''message'') '''Return''' ''sessionDigest'',''lastMessageId''
{{algorithm-end}}