Implement MIP-00 keypackage envelope validation

This commit is contained in:
2026-03-13 21:54:07 +01:00
parent 7646650fb9
commit cf5ae772b2
5 changed files with 367 additions and 8 deletions

View File

@@ -0,0 +1,83 @@
defmodule Parrhesia.Protocol.EventValidatorMarmotTest do
use ExUnit.Case, async: true
alias Parrhesia.Protocol
alias Parrhesia.Protocol.EventValidator
test "accepts valid MIP-00 keypackage envelope (kind 443)" do
event = valid_keypackage_event()
assert :ok = EventValidator.validate(event)
assert :ok = Protocol.validate_event(event)
end
test "rejects keypackage without required encoding tag" do
event =
valid_keypackage_event(%{
"tags" =>
Enum.reject(valid_keypackage_tags(), fn [name | _rest] -> name == "encoding" end)
})
assert {:error, :missing_marmot_encoding_tag} = EventValidator.validate(event)
assert {:error, "invalid: kind 443 must include [\"encoding\", \"base64\"]"} =
Protocol.validate_event(event)
end
test "rejects keypackage with non-base64 content" do
event = valid_keypackage_event(%{"content" => "%%%not-base64%%%"})
assert {:error, :invalid_marmot_keypackage_content} = EventValidator.validate(event)
end
test "accepts keypackage relay list envelope (kind 10051)" do
event = valid_keypackage_relay_list_event()
assert :ok = EventValidator.validate(event)
end
test "rejects keypackage relay list without relay tags" do
event = valid_keypackage_relay_list_event(%{"tags" => [["p", String.duplicate("f", 64)]]})
assert {:error, :missing_marmot_relay_tag} = EventValidator.validate(event)
end
defp valid_keypackage_event(overrides \\ %{}) do
base_event = %{
"pubkey" => String.duplicate("1", 64),
"created_at" => System.system_time(:second),
"kind" => 443,
"tags" => valid_keypackage_tags(),
"content" => Base.encode64("fake-keypackage-bundle"),
"sig" => String.duplicate("2", 128)
}
event = Map.merge(base_event, overrides)
Map.put(event, "id", EventValidator.compute_id(event))
end
defp valid_keypackage_tags do
[
["mls_protocol_version", "1.0"],
["mls_ciphersuite", "0x0001"],
["mls_extensions", "0xf2ee", "0x000a"],
["encoding", "base64"],
["i", String.duplicate("a", 64)],
["relays", "wss://relay.example.com"]
]
end
defp valid_keypackage_relay_list_event(overrides \\ %{}) do
base_event = %{
"pubkey" => String.duplicate("3", 64),
"created_at" => System.system_time(:second),
"kind" => 10_051,
"tags" => [["relay", "wss://relay.one"], ["relay", "wss://relay.two"]],
"content" => "",
"sig" => String.duplicate("4", 128)
}
event = Map.merge(base_event, overrides)
Map.put(event, "id", EventValidator.compute_id(event))
end
end

View File

@@ -245,6 +245,29 @@ defmodule Parrhesia.Storage.Adapters.Postgres.EventsQueryCountTest do
assert result["id"] == allowed["id"]
end
test "query/3 supports #i keypackage reference lookups" do
keypackage_ref = String.duplicate("a", 64)
matching =
persist_event(%{
"kind" => 443,
"tags" => [["i", keypackage_ref], ["encoding", "base64"]],
"content" => Base.encode64("keypackage")
})
_non_matching =
persist_event(%{
"kind" => 443,
"tags" => [["i", String.duplicate("b", 64)], ["encoding", "base64"]],
"content" => Base.encode64("other")
})
assert {:ok, [result]} =
Events.query(%{}, [%{"kinds" => [443], "#i" => [keypackage_ref]}], [])
assert result["id"] == matching["id"]
end
test "mls keypackage relay list kind 10051 follows replaceable conflict semantics" do
author = String.duplicate("c", 64)