mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-05-30 15:54:12 +00:00
hkdf for short links
This commit is contained in:
@@ -218,7 +218,9 @@ Each step produces working, tested code. Steps 1-11 work without block encryptio
|
||||
|
||||
**Done**. Function: `connShortLinkStrP` in `agent/protocol.ts`. Uses `base64urlDecode` from xftp-web `description.ts`.
|
||||
|
||||
**Future**: add long link parsing (`ConnectionRequestUri`) and an either-parser that handles both short and long links.
|
||||
**Future**:
|
||||
- Add long link parsing (`ConnectionRequestUri`) and an either-parser that handles both short and long links.
|
||||
- Add `restoreShortLink`: preset servers are shortened to host-only (`SMPServerOnlyHost` - no port, no keyHash). After parsing, `restoreShortLink` looks up the full server by hostname from a preset servers list. Without this, connections to preset servers will fail. See `Agent/Protocol.hs:1692`.
|
||||
|
||||
### Step 7: HKDF Key Derivation
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// Short link key derivation.
|
||||
// Mirrors: Simplex.Messaging.Crypto.ShortLink
|
||||
|
||||
import {hkdf} from "@noble/hashes/hkdf"
|
||||
import {sha512} from "@noble/hashes/sha512"
|
||||
|
||||
// contactShortLinkKdf (Agent/Protocol.hs:47-50)
|
||||
// hkdf("", linkKey, "SimpleXContactLink", 56) -> (linkId[24], sbKey[32])
|
||||
export function contactShortLinkKdf(linkKey: Uint8Array): {linkId: Uint8Array; sbKey: Uint8Array} {
|
||||
const derived = hkdf(sha512, linkKey, new Uint8Array(0), "SimpleXContactLink", 56)
|
||||
return {
|
||||
linkId: derived.slice(0, 24),
|
||||
sbKey: derived.slice(24, 56),
|
||||
}
|
||||
}
|
||||
|
||||
// invShortLinkKdf (Agent/Protocol.hs:52-53)
|
||||
// hkdf("", linkKey, "SimpleXInvLink", 32) -> sbKey[32]
|
||||
export function invShortLinkKdf(linkKey: Uint8Array): Uint8Array {
|
||||
return hkdf(sha512, linkKey, new Uint8Array(0), "SimpleXInvLink", 32)
|
||||
}
|
||||
+23
-1
@@ -18,9 +18,10 @@ import Data.List.NonEmpty (NonEmpty (..))
|
||||
import Data.Word (Word16)
|
||||
import qualified Simplex.Messaging.Agent.Protocol as AP
|
||||
import qualified Simplex.Messaging.Crypto as C
|
||||
import Simplex.Messaging.Crypto.ShortLink (contactShortLinkKdf, invShortLinkKdf)
|
||||
import Simplex.Messaging.Encoding
|
||||
import Simplex.Messaging.Encoding.String (strEncode)
|
||||
import Simplex.Messaging.Protocol (SMPServer, pattern SMPServer)
|
||||
import Simplex.Messaging.Protocol (EntityId (..), SMPServer, pattern SMPServer)
|
||||
import Simplex.Messaging.Server.Env.STM (AStoreType (..))
|
||||
import Simplex.Messaging.Server.MsgStore.Types (SMSType (..), SQSType (..))
|
||||
import Simplex.Messaging.Server.Web (attachStaticAndWS)
|
||||
@@ -52,6 +53,9 @@ impWS = "import { connectSMP, sendBlock, receiveBlock } from './dist/transport/w
|
||||
impAgentProto :: String
|
||||
impAgentProto = "import { connShortLinkStrP } from './dist/agent/protocol.js';"
|
||||
|
||||
impCryptoShortLink :: String
|
||||
impCryptoShortLink = "import { contactShortLinkKdf, invShortLinkKdf } from './dist/crypto/shortLink.js';"
|
||||
|
||||
jsStr :: B.ByteString -> String
|
||||
jsStr bs = "'" <> BC.unpack bs <> "'"
|
||||
|
||||
@@ -154,6 +158,24 @@ smpWebTests = describe "SMP Web Client" $ do
|
||||
<> "})")
|
||||
tsEncoded `shouldBe` hsEncoded
|
||||
|
||||
describe "crypto/shortLink" $ do
|
||||
describe "contactShortLinkKdf" $ do
|
||||
it "TypeScript produces same linkId and sbKey as Haskell" $ do
|
||||
let linkKey = AP.LinkKey $ B.pack [1..32]
|
||||
(EntityId hsLinkId, C.SbKey hsKey) = contactShortLinkKdf linkKey
|
||||
tsResult <- callNode $ impCryptoShortLink
|
||||
<> "const r = contactShortLinkKdf(" <> jsUint8 (B.pack [1..32]) <> ");"
|
||||
<> jsOut ("new Uint8Array([...r.linkId, ...r.sbKey])")
|
||||
tsResult `shouldBe` (hsLinkId <> hsKey)
|
||||
|
||||
describe "invShortLinkKdf" $ do
|
||||
it "TypeScript produces same sbKey as Haskell" $ do
|
||||
let linkKey = AP.LinkKey $ B.pack [50..81]
|
||||
C.SbKey hsKey = invShortLinkKdf linkKey
|
||||
tsResult <- callNode $ impCryptoShortLink
|
||||
<> jsOut ("invShortLinkKdf(" <> jsUint8 (B.pack [50..81]) <> ")")
|
||||
tsResult `shouldBe` hsKey
|
||||
|
||||
describe "agent/protocol" $ do
|
||||
describe "ConnShortLink" $ do
|
||||
it "parses simplex: contact link" $ do
|
||||
|
||||
Reference in New Issue
Block a user