From 0bc5659076a75ab266e1feb6d61b709d9cb5e42b Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 19 Oct 2026 10:34:59 +0200 Subject: [PATCH] Make every ask id end in a digest of its key so two keys never share an id (issue 1201) --- go/delivery/gate.go | 18 ++++++++++-------- go/delivery/gate_test.go | 4 +++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/go/delivery/gate.go b/go/delivery/gate.go index 8ef7ed3..51fdb44 100644 --- a/go/delivery/gate.go +++ b/go/delivery/gate.go @@ -94,16 +94,18 @@ func ParseAskKey(key string) (kind, group, hash string, err error) { func AnswerKey(askKey string) string { return askKey } // AskID is the id the teller gives the router for the ask at askKey. The router's ids refuse dots (asks.UsableID), -// so a dot becomes `-` and a slash `_`; a key too long for an id is cut and ends in a digest of the whole key. -// It cannot be read back: the teller keeps the key beside it. +// so in the readable part a dot becomes `-` and a slash `_`; that part is cut to fit, and every id ends in `-` and +// the first 12 hex digits of the sha256 of the whole key, so two keys never give one id. It cannot be read back: +// the teller keeps the key beside it. func AskID(askKey string) string { - id := strings.NewReplacer(".", "-", "/", "_").Replace(askKey) - const most = 64 - if len(id) > most { - sum := sha256.Sum256([]byte(askKey)) - id = id[:most-13] + "-" + hex.EncodeToString(sum[:])[:12] + const most = 64 // the router's bound on an id + const tail = 13 // "-" and 12 hex digits + readable := strings.NewReplacer(".", "-", "/", "_").Replace(askKey) + if len(readable) > most-tail { + readable = readable[:most-tail] } - return id + sum := sha256.Sum256([]byte(askKey)) + return readable + "-" + hex.EncodeToString(sum[:])[:12] } func checkOwedAct(act string) (kind, context string, err error) { diff --git a/go/delivery/gate_test.go b/go/delivery/gate_test.go index a8b53ff..4f6dcb7 100644 --- a/go/delivery/gate_test.go +++ b/go/delivery/gate_test.go @@ -55,8 +55,10 @@ func TestAskID(t *testing.T) { // 1201/AC2 k3, _ := MergeAskKey("feat/x", gateHeads()[:1]) long, _ := MergeAskKey("feat/"+strings.Repeat("long-", 20), gateHeads()) long2, _ := MergeAskKey("feat/"+strings.Repeat("long-", 20)+"2", gateHeads()) + slash, _ := MergeAskKey("a/b", gateHeads()) + under, _ := MergeAskKey("a_b", gateHeads()) seen := map[string]string{} - for _, k := range []string{k1, k2, k3, long, long2} { + for _, k := range []string{k1, k2, k3, long, long2, slash, under} { id := AskID(k) if strings.Contains(id, ".") { t.Errorf("id %q holds a dot", id)