Upon further reflection I think the simplest solution is to have 
MixDescriptor represent the maps of mix keys in raw bytes and use a method 
to unmarshal them when needed.
The unmarshal method could use CBOR tags to figure out which type to 
unmarshal into.... but it would be easier to implement this where a Sphinx 
Geometry object is an argument to the method which does the unmarshaling; 
and using that Sphinx Geometry to determine which concrete cryptographic 
key type should be used.

On Friday, February 10, 2023 at 6:19:55 PM UTC-5 David Stainton wrote:

>
> Greetings people of golang, cryptographers, software architects,
>
> Hi. I'm a Katzenpost developer, it's a software project, not a legal 
> entity: https://github.com/katzenpost
>
> We use the golang CBOR library: github.com/fxamacker/cbor
> Works great!
>
> Jumping right into the nitty gritty here... We have a "directory 
> authority" protocol (similar to Tor's directory authority protocol) which 
> votes and publishes a "network view" document which contains many 
> MixDescriptor objects, one for each network node (known as a mix).
> Each mix published several mix keys for future Epochs in their 
> MixDescriptor. So we have a map of these mix keys, like so:
>
>
> https://github.com/katzenpost/katzenpost/blob/main/core/pki/descriptor.go#L65
>
> However, currently the map of keys only stores X25519 keys. But ideally 
> we'd like the MixDescriptor struct to be more accommodating to migrating to 
> hybrid post quantum keys.
>
> How might we accomplish this?
> Acceptable solutions will not create intermediary types to represent the 
> entire MixDescriptor... but there should be no objections to intermediary 
> types for representing a single field of the MixDescriptor; like a wrapper 
> type for the map of mix keys?
>
> Also... can I just point out now that two of the MixDescriptor fields are 
> interface types representing two different kinds of cryptographic public 
> key, yet we manage to CBOR unmarshal everything just fine without an 
> intermediary type, with this trick here:
>
>
> https://github.com/katzenpost/katzenpost/blob/main/core/pki/descriptor.go#L123-L127
>
> So we initialize those two fields with valid empty types that implement 
> those interfaces. Fine. But that won't work for a map of interface types, 
> right?
>
> Let's come back to this question soon, and now take a brief digression to 
> discuss katzenpost architecture design:
>
> These mix keys are used by a nested encrypted packet format known as 
> Sphinx (here's the paper 
> https://www.cypherpunks.ca/~iang/pubs/Sphinx_Oakland09.pdf ). Long story 
> short, our Sphinx can use any NIKE (non-interactive key exchange e.g. 
> X25519) and any KEM (key encapsulation mechanism):
>
> code: https://github.com/katzenpost/katzenpost/tree/main/core/sphinx
> design spec: 
> https://github.com/katzenpost/katzenpost/blob/main/docs/specs/sphinx.rst
> design amendment for KEM: 
> https://github.com/katzenpost/katzenpost/blob/main/docs/specs/kemsphinx.rst
>
> Backing up a bit, our "directory authority" publishes a document of this 
> type:
> https://github.com/katzenpost/katzenpost/blob/main/core/pki/document.go#L77
>
> which contains many MixDescriptor objects for the entire network:
>
> https://github.com/katzenpost/katzenpost/blob/main/core/pki/document.go#L128
>
> Currently all network components use Sphinx with a geometry that is 
> hardcoded. However I've got a work-in-progress branch where I'm changing 
> things to distribute the Sphinx geometry in the directory authority 
> document:
>
>
> https://github.com/katzenpost/katzenpost/blob/sphinx_geo_pki/core/sphinx/geo/geo.go#L31-L89
>
>
> https://github.com/katzenpost/katzenpost/blob/sphinx_geo_pki/core/pki/document.go#L152
>
> The Sphinx Geometry describes it's KEM or NIKE:
>
> https://github.com/katzenpost/katzenpost/blob/sphinx_geo_pki/core/sphinx/geo/geo.go#L82-L88
>
> So I guess my question is: How shall I marshal/unmarshal a map of public 
> keys where the keys themselves can be any type that satisfies our NIKE 
> interface or KEM inteface?
>
> It would be silly to put a bunch of concrete key maps into MixDescriptor. 
> There will always be more KEMs and NIKEs.
>
> It sounds like I need change the MixKeys field of the MixDescriptor to use 
> a wrapper type instead of a map directly. The wrapper type would have it's 
> own UnmarshalBinary/MarshalBinary (so that cbor.Marshal/Unmarshal can be 
> called) which would represent the map as a list of two tuples: key, value. 
> Easy to convert it to a map.
>
> What do you think of this approach?
>
> type KeyValue struct {
>         Key uint64
>         Value mixkey.PublicKey
> }
>
> ...blah blah...
>
> fubar := make([]KeyValue, 123)
> cbor.Unmarshal(blob, fubar)
>
> But can this work if mixkey.PublicKey is an interface? Nope. I don't think 
> that works because the nil value of KeyValue struct will have a nil for 
> it's Value field.
>
> Any suggestions?
>
> Cheers,
>
> David
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ce8a5822-d2a5-4230-858b-00f69a5c4e5bn%40googlegroups.com.

Reply via email to