diff options
| author | Gab <24553253+gabrix73@users.noreply.github.com> | 2026-08-14 20:39:22 +0200 |
|---|---|---|
| committer | Gab <24553253+gabrix73@users.noreply.github.com> | 2026-08-14 20:39:22 +0200 |
| commit | 43fbddf016f94f4ba006d82c9a67dca61b5852a1 (patch) | |
| tree | 70054d5fa8a34bb094b8c3ef8ddc9c1fcea3b3d5 /katzenpost | |
| parent | 994071243fc80990cf09e820b671006e9bd31c76 (diff) | |
| download | yamnweb-43fbddf016f94f4ba006d82c9a67dca61b5852a1.tar.gz yamnweb-43fbddf016f94f4ba006d82c9a67dca61b5852a1.tar.xz yamnweb-43fbddf016f94f4ba006d82c9a67dca61b5852a1.zip | |
Complete Nym and YAMN transport integration
Diffstat (limited to 'katzenpost')
| -rw-r--r-- | katzenpost/README.md | 30 | ||||
| -rw-r--r-- | katzenpost/cmd/yamn-dispatcher/main.go | 115 | ||||
| -rw-r--r-- | katzenpost/cmd/yamn-submit/main.go | 73 | ||||
| -rw-r--r-- | katzenpost/dispatcher/codec.go | 29 | ||||
| -rw-r--r-- | katzenpost/dispatcher/envelope.go | 45 | ||||
| -rw-r--r-- | katzenpost/dispatcher/envelope_test.go | 21 | ||||
| -rw-r--r-- | katzenpost/dispatcher/frame.go | 84 | ||||
| -rw-r--r-- | katzenpost/dispatcher/frame_test.go | 46 | ||||
| -rw-r--r-- | katzenpost/dispatcher/reassembler.go | 91 | ||||
| -rw-r--r-- | katzenpost/go.mod | 35 | ||||
| -rw-r--r-- | katzenpost/go.sum | 63 |
11 files changed, 0 insertions, 632 deletions
diff --git a/katzenpost/README.md b/katzenpost/README.md deleted file mode 100644 index 938c2b0..0000000 --- a/katzenpost/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Katzenpost YAMN dispatcher - -The dispatcher runs on `kvara`. It is a send-only Katzenpost service: it -receives an already encrypted YAMN packet and forwards it to the selected YAMN -entry remailer using SMTP. It never receives a browser request and must not -implement fetch, view, AEC, replies, or message storage. - -`pietro` is responsible for building the YAMN packet and submitting the opaque -envelope to the Katzenpost service through `kpclientd`. - -## Trust boundary - -The only data the dispatcher may see is: - -- the entry remailer SMTP address; -- the complete, already encrypted YAMN envelope. - -It must reject all other recipient domains and must not write payloads, -subjects, addresses, or SMTP transcripts to disk or logs. - -## Deployment shape - -```text -pietro: yamnweb onion service -> local kpclientd -> Katzenpost - -> kvara dispatcher -> YAMN entry SMTP -``` - -The service capability name is `yamn-dispatch-v1`. It must be registered in -the Katzenpost PKI before `pietro` can discover it. The code is intentionally -not configured with live hosts, credentials, or service keys. diff --git a/katzenpost/cmd/yamn-dispatcher/main.go b/katzenpost/cmd/yamn-dispatcher/main.go deleted file mode 100644 index 8f10034..0000000 --- a/katzenpost/cmd/yamn-dispatcher/main.go +++ /dev/null @@ -1,115 +0,0 @@ -package main - -import ( - "errors" - "flag" - "fmt" - "os" - "path/filepath" - "strings" - "time" - - "git.virebent.art/virebent/yamnweb/katzenpost/dispatcher" - "github.com/katzenpost/katzenpost/core/log" - "github.com/katzenpost/katzenpost/server/cborplugin" -) - -const capability = "yamn-dispatch-v1" - -type plugin struct { - write func(cborplugin.Command) - reassembler *dispatcher.Reassembler - allowedDomains map[string]struct{} -} - -func (p *plugin) OnCommand(command cborplugin.Command) error { - request, ok := command.(*cborplugin.Request) - if !ok { - return errors.New("unexpected plugin command") - } - frame, err := dispatcher.DecodeFrame(request.Payload) - if err != nil { - return err - } - encoded, complete, err := p.reassembler.Add(frame) - if err != nil || !complete { - return err - } - envelope, err := dispatcher.DecodeEnvelope(encoded) - if err != nil { - return err - } - if err := envelope.Validate(p.allowedDomains); err != nil { - return err - } - // PoC sink: successful validation intentionally has no external side effect. - return nil -} - -func (p *plugin) RegisterConsumer(server *cborplugin.Server) { - p.write = server.Write -} - -func parseDomains(value string) (map[string]struct{}, error) { - domains := make(map[string]struct{}) - for _, domain := range strings.Split(value, ",") { - domain = strings.ToLower(strings.TrimSpace(domain)) - if domain == "" || strings.ContainsAny(domain, "@/\\: ") { - return nil, errors.New("invalid allowed domain") - } - domains[domain] = struct{}{} - } - if len(domains) == 0 { - return nil, errors.New("at least one allowed domain is required") - } - return domains, nil -} - -func run() error { - var allowed string - var logDir string - var logLevel string - flag.StringVar(&allowed, "allowed-domains", "remailer.example", "comma-separated entry remailer domains") - flag.StringVar(&logDir, "log-dir", "/tmp", "operational log directory") - flag.StringVar(&logLevel, "log-level", "NOTICE", "Katzenpost log level") - flag.Parse() - - domains, err := parseDomains(allowed) - if err != nil { - return err - } - info, err := os.Stat(logDir) - if err != nil || !info.IsDir() { - return errors.New("log directory is unavailable") - } - backend, err := log.New(filepath.Join(logDir, "yamn-dispatch.log"), logLevel, false) - if err != nil { - return fmt.Errorf("initialize logging: %w", err) - } - logger := backend.GetLogger("yamn_dispatch") - - socketDir, err := os.MkdirTemp("", "yamn-dispatch-") - if err != nil { - return fmt.Errorf("create socket directory: %w", err) - } - defer os.RemoveAll(socketDir) - socketPath := filepath.Join(socketDir, "plugin.sock") - service := &plugin{ - reassembler: dispatcher.NewReassembler(5 * time.Minute), - allowedDomains: domains, - } - server := cborplugin.NewServer(logger, socketPath, new(cborplugin.RequestFactory), service) - if _, err := fmt.Fprintln(os.Stdout, socketPath); err != nil { - return fmt.Errorf("publish socket path: %w", err) - } - server.Accept() - server.Wait() - return nil -} - -func main() { - if err := run(); err != nil { - fmt.Fprintln(os.Stderr, "yamn-dispatcher failed") - os.Exit(1) - } -} diff --git a/katzenpost/cmd/yamn-submit/main.go b/katzenpost/cmd/yamn-submit/main.go deleted file mode 100644 index cde35f9..0000000 --- a/katzenpost/cmd/yamn-submit/main.go +++ /dev/null @@ -1,73 +0,0 @@ -package main - -import ( - "encoding/json" - "errors" - "flag" - "fmt" - "io" - "os" - "time" - - "git.virebent.art/virebent/yamnweb/katzenpost/dispatcher" - "github.com/katzenpost/hpqc/hash" - clientconfig "github.com/katzenpost/katzenpost/client/config" - "github.com/katzenpost/katzenpost/client/thin" -) - -const capability = "yamn-dispatch-v1" - -func run() error { - var configPath string - var settle time.Duration - flag.StringVar(&configPath, "config", "thinclient.toml", "thin-client configuration") - flag.DurationVar(&settle, "settle", 2*time.Second, "time allowed for kpclientd to queue frames") - flag.Parse() - - input, err := io.ReadAll(io.LimitReader(os.Stdin, dispatcher.MaxEnvelopeBytes*2)) - if err != nil { - return fmt.Errorf("read envelope: %w", err) - } - var envelope dispatcher.Envelope - if err := json.Unmarshal(input, &envelope); err != nil { - return errors.New("invalid envelope input") - } - encoded, err := dispatcher.EncodeEnvelope(envelope) - if err != nil { - return err - } - frames, err := dispatcher.SplitEnvelope(encoded) - if err != nil { - return err - } - - config, err := thin.LoadFile(configPath) - if err != nil { - return fmt.Errorf("load thin-client config: %w", err) - } - client := thin.NewThinClient(config, &clientconfig.Logging{Level: "ERROR", Disable: true}) - defer client.Close() - if err := client.Dial(); err != nil { - return fmt.Errorf("connect to kpclientd: %w", err) - } - service, err := client.GetService(capability) - if err != nil { - return fmt.Errorf("find dispatcher service: %w", err) - } - destination := hash.Sum256(service.MixDescriptor.IdentityKey) - for _, frame := range frames { - if err := client.SendMessageWithoutReply(frame, &destination, service.RecipientQueueID); err != nil { - return fmt.Errorf("send frame: %w", err) - } - } - time.Sleep(settle) - fmt.Fprintln(os.Stdout, "accepted") - return nil -} - -func main() { - if err := run(); err != nil { - fmt.Fprintf(os.Stderr, "submission failed: %v\n", err) - os.Exit(1) - } -} diff --git a/katzenpost/dispatcher/codec.go b/katzenpost/dispatcher/codec.go deleted file mode 100644 index 3053dde..0000000 --- a/katzenpost/dispatcher/codec.go +++ /dev/null @@ -1,29 +0,0 @@ -package dispatcher - -import ( - "fmt" - - "github.com/fxamacker/cbor/v2" -) - -func EncodeEnvelope(envelope Envelope) ([]byte, error) { - encoded, err := cbor.Marshal(envelope) - if err != nil { - return nil, fmt.Errorf("encode envelope: %w", err) - } - if len(encoded) > MaxEnvelopeBytes { - return nil, fmt.Errorf("encoded envelope is too large") - } - return encoded, nil -} - -func DecodeEnvelope(encoded []byte) (Envelope, error) { - if len(encoded) == 0 || len(encoded) > MaxEnvelopeBytes { - return Envelope{}, fmt.Errorf("invalid encoded envelope size") - } - var envelope Envelope - if err := cbor.Unmarshal(encoded, &envelope); err != nil { - return Envelope{}, fmt.Errorf("decode envelope: %w", err) - } - return envelope, nil -} diff --git a/katzenpost/dispatcher/envelope.go b/katzenpost/dispatcher/envelope.go deleted file mode 100644 index b9ff7b8..0000000 --- a/katzenpost/dispatcher/envelope.go +++ /dev/null @@ -1,45 +0,0 @@ -package dispatcher - -import ( - "bytes" - "errors" - "fmt" - "net/mail" - "strings" -) - -const MaxEnvelopeBytes = 64 * 1024 - -// Envelope is the only application payload accepted by the dispatcher. Message -// must already be a complete YAMN transport envelope, not user supplied mail. -type Envelope struct { - EntryAddress string `json:"entry_address"` - Message []byte `json:"message"` -} - -func (e Envelope) Validate(allowedDomains map[string]struct{}) error { - if len(e.Message) == 0 || len(e.Message) > MaxEnvelopeBytes { - return fmt.Errorf("invalid YAMN envelope size") - } - if bytes.Contains(e.Message, []byte("\r")) { - return errors.New("YAMN envelope must use LF line endings") - } - address, err := mail.ParseAddress(e.EntryAddress) - if err != nil || address.Address != e.EntryAddress { - return errors.New("invalid entry remailer address") - } - parts := strings.Split(address.Address, "@") - if len(parts) != 2 || parts[0] == "" || parts[1] == "" { - return errors.New("invalid entry remailer address") - } - if _, ok := allowedDomains[strings.ToLower(parts[1])]; !ok { - return errors.New("entry remailer domain is not allowed") - } - if !bytes.HasPrefix(e.Message, []byte("To: "+e.EntryAddress+"\n")) { - return errors.New("YAMN envelope recipient does not match entry remailer") - } - if !bytes.Contains(e.Message, []byte("-----BEGIN REMAILER MESSAGE-----\n")) { - return errors.New("invalid YAMN envelope") - } - return nil -} diff --git a/katzenpost/dispatcher/envelope_test.go b/katzenpost/dispatcher/envelope_test.go deleted file mode 100644 index 712071c..0000000 --- a/katzenpost/dispatcher/envelope_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package dispatcher - -import "testing" - -func TestEnvelopeValidate(t *testing.T) { - allowed := map[string]struct{}{"remailer.example": {}} - valid := Envelope{ - EntryAddress: "entry@remailer.example", - Message: []byte("To: entry@remailer.example\nFrom: mix@nowhere.invalid\n\n-----BEGIN REMAILER MESSAGE-----\nabc\n"), - } - if err := valid.Validate(allowed); err != nil { - t.Fatalf("expected valid envelope: %v", err) - } - - invalidDomain := valid - invalidDomain.EntryAddress = "entry@other.example" - invalidDomain.Message = []byte("To: entry@other.example\n-----BEGIN REMAILER MESSAGE-----\n") - if err := invalidDomain.Validate(allowed); err == nil { - t.Fatal("expected unknown domain rejection") - } -} diff --git a/katzenpost/dispatcher/frame.go b/katzenpost/dispatcher/frame.go deleted file mode 100644 index 43f547c..0000000 --- a/katzenpost/dispatcher/frame.go +++ /dev/null @@ -1,84 +0,0 @@ -package dispatcher - -import ( - "crypto/rand" - "crypto/sha256" - "errors" - "fmt" - - "github.com/fxamacker/cbor/v2" -) - -const ( - ProtocolVersion = 1 - MaxSphinxPayload = 2000 - FrameDataBytes = 1500 - MaxFrames = (MaxEnvelopeBytes + FrameDataBytes - 1) / FrameDataBytes -) - -type Frame struct { - Version uint8 `cbor:"1,keyasint"` - ID [16]byte `cbor:"2,keyasint"` - Digest [32]byte `cbor:"3,keyasint"` - Index uint16 `cbor:"4,keyasint"` - Total uint16 `cbor:"5,keyasint"` - Data []byte `cbor:"6,keyasint"` -} - -func SplitEnvelope(encoded []byte) ([][]byte, error) { - if len(encoded) == 0 || len(encoded) > MaxEnvelopeBytes { - return nil, errors.New("invalid encoded envelope size") - } - - var id [16]byte - if _, err := rand.Read(id[:]); err != nil { - return nil, fmt.Errorf("generate message id: %w", err) - } - digest := sha256.Sum256(encoded) - total := (len(encoded) + FrameDataBytes - 1) / FrameDataBytes - if total > MaxFrames { - return nil, errors.New("encoded envelope requires too many frames") - } - - frames := make([][]byte, 0, total) - for index, start := 0, 0; start < len(encoded); index, start = index+1, start+FrameDataBytes { - end := min(start+FrameDataBytes, len(encoded)) - frame := Frame{ - Version: ProtocolVersion, - ID: id, - Digest: digest, - Index: uint16(index), - Total: uint16(total), - Data: encoded[start:end], - } - payload, err := cbor.Marshal(frame) - if err != nil { - return nil, fmt.Errorf("encode frame %d: %w", index, err) - } - if len(payload) > MaxSphinxPayload { - return nil, fmt.Errorf("frame %d exceeds Sphinx payload limit", index) - } - frames = append(frames, payload) - } - return frames, nil -} - -func DecodeFrame(payload []byte) (Frame, error) { - if len(payload) == 0 || len(payload) > MaxSphinxPayload { - return Frame{}, errors.New("invalid frame size") - } - var frame Frame - if err := cbor.Unmarshal(payload, &frame); err != nil { - return Frame{}, fmt.Errorf("decode frame: %w", err) - } - if frame.Version != ProtocolVersion { - return Frame{}, errors.New("unsupported frame version") - } - if frame.Total == 0 || int(frame.Total) > MaxFrames || frame.Index >= frame.Total { - return Frame{}, errors.New("invalid frame sequence") - } - if len(frame.Data) == 0 || len(frame.Data) > FrameDataBytes { - return Frame{}, errors.New("invalid frame data size") - } - return frame, nil -} diff --git a/katzenpost/dispatcher/frame_test.go b/katzenpost/dispatcher/frame_test.go deleted file mode 100644 index 21c84ba..0000000 --- a/katzenpost/dispatcher/frame_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package dispatcher - -import ( - "bytes" - "testing" - "time" -) - -func TestSplitAndReassembleEnvelope(t *testing.T) { - encoded := bytes.Repeat([]byte("yamn-envelope\n"), 900) - payloads, err := SplitEnvelope(encoded) - if err != nil { - t.Fatal(err) - } - if len(payloads) < 2 { - t.Fatal("expected multiple frames") - } - - reassembler := NewReassembler(time.Minute) - var result []byte - for _, payload := range payloads { - if len(payload) > MaxSphinxPayload { - t.Fatalf("payload exceeds limit: %d", len(payload)) - } - frame, err := DecodeFrame(payload) - if err != nil { - t.Fatal(err) - } - assembled, complete, err := reassembler.Add(frame) - if err != nil { - t.Fatal(err) - } - if complete { - result = assembled - } - } - if !bytes.Equal(result, encoded) { - t.Fatal("reassembled envelope differs") - } -} - -func TestDecodeFrameRejectsOversizedPayload(t *testing.T) { - if _, err := DecodeFrame(make([]byte, MaxSphinxPayload+1)); err == nil { - t.Fatal("expected oversized payload rejection") - } -} diff --git a/katzenpost/dispatcher/reassembler.go b/katzenpost/dispatcher/reassembler.go deleted file mode 100644 index 87af98c..0000000 --- a/katzenpost/dispatcher/reassembler.go +++ /dev/null @@ -1,91 +0,0 @@ -package dispatcher - -import ( - "bytes" - "crypto/sha256" - "errors" - "sync" - "time" -) - -const MaxPendingMessages = 64 - -type pendingMessage struct { - digest [32]byte - total uint16 - parts map[uint16][]byte - created time.Time -} - -type Reassembler struct { - mu sync.Mutex - pending map[[16]byte]*pendingMessage - ttl time.Duration - now func() time.Time -} - -func NewReassembler(ttl time.Duration) *Reassembler { - return &Reassembler{ - pending: make(map[[16]byte]*pendingMessage), - ttl: ttl, - now: time.Now, - } -} - -func (r *Reassembler) Add(frame Frame) ([]byte, bool, error) { - r.mu.Lock() - defer r.mu.Unlock() - - r.expireLocked() - pending, ok := r.pending[frame.ID] - if !ok { - if len(r.pending) >= MaxPendingMessages { - return nil, false, errors.New("too many pending messages") - } - pending = &pendingMessage{ - digest: frame.Digest, - total: frame.Total, - parts: make(map[uint16][]byte, frame.Total), - created: r.now(), - } - r.pending[frame.ID] = pending - } - if pending.total != frame.Total || pending.digest != frame.Digest { - delete(r.pending, frame.ID) - return nil, false, errors.New("inconsistent frame metadata") - } - if _, duplicate := pending.parts[frame.Index]; !duplicate { - pending.parts[frame.Index] = bytes.Clone(frame.Data) - } - if len(pending.parts) != int(pending.total) { - return nil, false, nil - } - - var assembled bytes.Buffer - for index := uint16(0); index < pending.total; index++ { - part, exists := pending.parts[index] - if !exists { - return nil, false, nil - } - if assembled.Len()+len(part) > MaxEnvelopeBytes { - delete(r.pending, frame.ID) - return nil, false, errors.New("reassembled envelope is too large") - } - assembled.Write(part) - } - delete(r.pending, frame.ID) - result := assembled.Bytes() - if sha256.Sum256(result) != pending.digest { - return nil, false, errors.New("reassembled envelope digest mismatch") - } - return result, true, nil -} - -func (r *Reassembler) expireLocked() { - cutoff := r.now().Add(-r.ttl) - for id, pending := range r.pending { - if pending.created.Before(cutoff) { - delete(r.pending, id) - } - } -} diff --git a/katzenpost/go.mod b/katzenpost/go.mod deleted file mode 100644 index 09a9aca..0000000 --- a/katzenpost/go.mod +++ /dev/null @@ -1,35 +0,0 @@ -module git.virebent.art/virebent/yamnweb/katzenpost - -go 1.26.2 - -require ( - github.com/fxamacker/cbor/v2 v2.9.1 - github.com/katzenpost/hpqc v0.0.84-0.20260603082753-be60338910ec - github.com/katzenpost/katzenpost v0.0.90 -) - -require ( - codeberg.org/vula/highctidh v1.0.2025051200 // indirect - filippo.io/edwards25519 v1.2.0 // indirect - filippo.io/mldsa v0.0.0-20260215214346-43d0283efc3e // indirect - filippo.io/mlkem768 v0.0.0-20260214141301-2e7bebc7d88d // indirect - github.com/BurntSushi/toml v1.6.0 // indirect - github.com/agl/gcmsiv v0.0.0-20190418185415-e8dcd2f151dc // indirect - github.com/katzenpost/chacha20 v0.0.1 // indirect - github.com/katzenpost/chacha20poly1305 v0.0.1 // indirect - github.com/katzenpost/circl v1.3.8-0.20260413165442-e2d217fd59f5 // indirect - github.com/katzenpost/falcon v0.1.0 // indirect - github.com/katzenpost/sntrup4591761 v0.0.0-20231024131303-8755eb1986b8 // indirect - github.com/katzenpost/sphincsplus v0.0.2 // indirect - github.com/katzenpost/sqisign/bindings/go v0.0.0-20260520215053-47e926d8264d // indirect - github.com/mattn/go-pointer v0.0.1 // indirect - github.com/shurlinet/go-hqc v0.1.1 // indirect - github.com/x448/float16 v0.8.4 // indirect - gitlab.com/yawning/aez.git v0.0.0-20211027044916-e49e68abd344 // indirect - gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect - golang.org/x/crypto v0.51.0 // indirect - golang.org/x/net v0.53.0 // indirect - golang.org/x/sys v0.44.0 // indirect - golang.org/x/text v0.37.0 // indirect - gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 // indirect -) diff --git a/katzenpost/go.sum b/katzenpost/go.sum deleted file mode 100644 index d8d6abd..0000000 --- a/katzenpost/go.sum +++ /dev/null @@ -1,63 +0,0 @@ -codeberg.org/vula/highctidh v1.0.2025051200 h1:4xG2pxCCYKvI2HICy5YQf+44d8pEibuOg4u86PvX4OM= -codeberg.org/vula/highctidh v1.0.2025051200/go.mod h1:admvznk7GhsrDih/BMy7jbIv9Y86U9vj7S5FVoquF/g= -filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= -filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= -filippo.io/mldsa v0.0.0-20260215214346-43d0283efc3e h1:VsUbObBMxXlc23Eb9VeeJYE4jvTs87qa5RqSN2U5FJU= -filippo.io/mldsa v0.0.0-20260215214346-43d0283efc3e/go.mod h1:32qQ5yj3R24Eu03iWFWchdC3OB653wPvoepWejkefbY= -filippo.io/mlkem768 v0.0.0-20260214141301-2e7bebc7d88d h1:YyLyABjdrdt2l/E6JAnku4BjhEDXhxQD2bPOnOvy8/M= -filippo.io/mlkem768 v0.0.0-20260214141301-2e7bebc7d88d/go.mod h1:ym4egWKLpazdho3bHx0xuQlCq02ttP+vhxxKO8LgO9c= -github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= -github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/agl/gcmsiv v0.0.0-20190418185415-e8dcd2f151dc h1:MB338WDPuyQ8qXRiSRK2NVTv0EmLYsHXZAevEiQO1+c= -github.com/agl/gcmsiv v0.0.0-20190418185415-e8dcd2f151dc/go.mod h1:5joDAvk82M2Cx1X8mAL5Orvhy5lfW4BjrTCW65wbvRo= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ= -github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= -github.com/katzenpost/chacha20 v0.0.1 h1:Scu6Pqyginw083FhypKMIBmCI2gQTC1RFD6vqpWwI2Y= -github.com/katzenpost/chacha20 v0.0.1/go.mod h1:/LIJK/8cUXVJrCh5NypZ8So3gDfQCoQT8lRvy1rYQZA= -github.com/katzenpost/chacha20poly1305 v0.0.1 h1:yFPxgu/VSWsoCNQ2x15az8xBKKc/9GDY9Pz42MvY9xg= -github.com/katzenpost/chacha20poly1305 v0.0.1/go.mod h1:5sv//C8pWaXrnnP3CNiJXqAlA1/yfUZOl1tR9xsL9bI= -github.com/katzenpost/circl v1.3.8-0.20260413165442-e2d217fd59f5 h1:n+9aUwSmnz97MNS9duYeHSq+s42CG9wydFECOjqAI9A= -github.com/katzenpost/circl v1.3.8-0.20260413165442-e2d217fd59f5/go.mod h1:9KxLMK17ZLjofnmpVp4Sm315uIF3BAWHVk32EFDRicU= -github.com/katzenpost/falcon v0.1.0 h1:+WkID41Y6CaWAQE3ijCIfZHu7eHHy8DvAFWCnrW1XDw= -github.com/katzenpost/falcon v0.1.0/go.mod h1:HtOnkNvwpvTJ3fuXmy4BNw4A8Jg2QetpmkvOPOnOwyU= -github.com/katzenpost/hpqc v0.0.84-0.20260603082753-be60338910ec h1:6YnGxqJXmAXt9maeTudPdNmEjG4hLJkRj8ISpih9TJU= -github.com/katzenpost/hpqc v0.0.84-0.20260603082753-be60338910ec/go.mod h1:C/MaI/ke/uHR5FCKuqB/GNa/JLoFk9PeBnFoP23dh6Q= -github.com/katzenpost/katzenpost v0.0.90 h1:z3bBMpDK3eC65kqbXGwlIjIo1IccHTWytgCCtX+PL2M= -github.com/katzenpost/katzenpost v0.0.90/go.mod h1:tKMbNtHwBxv2qk9uX5hfNueFnxpQPDvr6NjkW5AUchY= -github.com/katzenpost/sntrup4591761 v0.0.0-20231024131303-8755eb1986b8 h1:TsKxH0x2RUwf5rBw67k15bqVM3oVbexA9oaTZQLIy3Y= -github.com/katzenpost/sntrup4591761 v0.0.0-20231024131303-8755eb1986b8/go.mod h1:Hmcrwom7jcEmGdo0CsyuJNnldPeyS+M07FuCbo7I8fw= -github.com/katzenpost/sphincsplus v0.0.2 h1:W1UWejLK62Lk0uK2R08H/sWEaQrRHWCaMEKO181SoOE= -github.com/katzenpost/sphincsplus v0.0.2/go.mod h1:ChO9+ojgCH1yEuplGgW4mSI1FwZWtyEmEkG1xL3w264= -github.com/katzenpost/sqisign/bindings/go v0.0.0-20260520215053-47e926d8264d h1:mjXmMwB8NRO0+NoUGj9zys2vm02Ia9on0lZE5gVr4X8= -github.com/katzenpost/sqisign/bindings/go v0.0.0-20260520215053-47e926d8264d/go.mod h1:CcVAF5BHgQtHH3lFCmwl3t2KKcXih+8ZcjLbxg8z3D0= -github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= -github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/schwarmco/go-cartesian-product v0.0.0-20230921023625-e02d1c150053 h1:h7EwPM2KjupG0zVAG+EYxbR2cHnbiP1d4DTAZ+G09LY= -github.com/schwarmco/go-cartesian-product v0.0.0-20230921023625-e02d1c150053/go.mod h1:/TRiIlxvQQAtfnBXEqqbnYBYPmE6XT5iZxSx+hJ9zGw= -github.com/shurlinet/go-hqc v0.1.1 h1:p0ZSHW+Spulp0pBnuyYTjgqmqm0CkILZWyOEZeKRXl0= -github.com/shurlinet/go-hqc v0.1.1/go.mod h1:3pQdozY8+F4AcOpiyj/ztKR90TwMDMBjbiNHNbejPtw= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -gitlab.com/yawning/aez.git v0.0.0-20211027044916-e49e68abd344 h1:eICJMpqnDkO4nQv+GWtXcE45CFum/ni3jhcE+acBjQk= -gitlab.com/yawning/aez.git v0.0.0-20211027044916-e49e68abd344/go.mod h1:/WDFxZLKGy+NQc+nqvQg2O0rW1HeWNHSelVv5fwEL8s= -gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo= -gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ= -golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= -golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= -golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= -golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= -golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= -gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 h1:6D+BvnJ/j6e222UW8s2qTSe3wGBtvo0MbVQG/c5k8RE= -gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
