[go-nuts] Re: CBOR / pq cryptography migration / software architecture golang question
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 { &
[go-nuts] CBOR / pq cryptography migration / software architecture golang question
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/0f0cb548-66ce-4499-91ef-3faa497ad41cn%40googlegroups.com.
Re: [go-nuts] cgo C.uint64_t compatiblity on multiple platforms?
Thanks, yes switching those type casts to C.size_t worked. On Saturday, December 3, 2022 at 2:39:24 PM UTC-5 kortschak wrote: > On Sat, 2022-12-03 at 10:51 -0800, David Stainton wrote: > > Greetings, > > > > I think my question is something like: "how to make my usage of > > C.uint64_t work on all platforms?" or "Is there something obviously > > wrong with my cgo bindings that is causing this not to build on all > > platforms?" > > > > I wrote this cgo binding for the reference implementation of Sphincs+ > > (it's a hash based post quantum signature scheme): > > > > > https://github.com/katzenpost/katzenpost/blob/main/sphincsplus/ref/binding.go > > > > Recently we noticed it fails to build on MacOS and Windows: > > > > > https://github.com/katzenpost/katzen/actions/runs/3609590801/jobs/6082872618 > > > > So I "fixed" it by changing the typecast to use C.uint64_t instead of > > C.ulong: > > > > https://github.com/katzenpost/katzenpost/pull/110/files > > > > However that causes the build to fail using Go1.19.3 on MacOS, > > although it works on Windows: > > > > > https://github.com/katzenpost/katzen/actions/runs/3609771045/jobs/6083165054 > > > > > > Sincerely, > > David Stainton > > The header file definition for crypto_sign_signature uses size_t for > the parameters that are passed as ulong in the calls that are causing > the issue. These types are not always the same size, so perhaps in e.g. > > https://github.com/katzenpost/katzenpost/blob/a165cb2a13e40f3a15dd1fa296a7763d8b638ae0/sphincsplus/ref/binding.go#L120-L125 > making the ulong params be size_t would help. > > -- 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/ff839488-59ff-45d8-bd01-ebc47a9a473an%40googlegroups.com.
[go-nuts] cgo C.uint64_t compatiblity on multiple platforms?
Greetings, I think my question is something like: "how to make my usage of C.uint64_t work on all platforms?" or "Is there something obviously wrong with my cgo bindings that is causing this not to build on all platforms?" I wrote this cgo binding for the reference implementation of Sphincs+ (it's a hash based post quantum signature scheme): https://github.com/katzenpost/katzenpost/blob/main/sphincsplus/ref/binding.go Recently we noticed it fails to build on MacOS and Windows: https://github.com/katzenpost/katzen/actions/runs/3609590801/jobs/6082872618 So I "fixed" it by changing the typecast to use C.uint64_t instead of C.ulong: https://github.com/katzenpost/katzenpost/pull/110/files However that causes the build to fail using Go1.19.3 on MacOS, although it works on Windows: https://github.com/katzenpost/katzen/actions/runs/3609771045/jobs/6083165054 Sincerely, David Stainton -- 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/86bdb5ce-d4ce-474e-bc98-01f7a8dce9fcn%40googlegroups.com.
[go-nuts] Re: cgo: how to pass an entropy source from golang to C?
I think the cleanest way to solve this problem is to use the go-pointers library and pass in the opaque pointer from the application through to the go callback. Here's a blog post I found detailing how this is done: https://eli.thegreenplace.net/2019/passing-callbacks-and-pointers-to-cgo/ On Tuesday, October 18, 2022 at 9:50:21 PM UTC-4 David Stainton wrote: > > Okay here I've tried a similar solution to the go-pointers library... but > i had to change it a bit to fit how the C library uses the context pointer: > > https://git.xx.network/elixxir/ctidh_cgo/-/commit/8f02611b943c269eab5b6e888958e4d41d72cd51 > > It builds and runs... and then panics on the "rng is nil"... not sure why. > So I'm going to try another solution where I change the C api slightly. > > I'm convinced there are many possible solutions to this and picking one is > a matter of deciding among a few tradeoffs. > > > On Tuesday, October 18, 2022 at 6:33:11 PM UTC-4 David Stainton wrote: > >> Greetings cgo experts, perhaps this post might also be of some interest >> to cryptography people as well. >> >> What's the best way for a C cryptography library to receive entropy from >> golang? >> >> There exists a C cryptography library (CTIDH, it's a PQ NIKE)... I am >> collaborating with C programmers who are adding features to it. I maintain >> cgo bindings for this library. Thus far the cgo is straight forward and it >> works. However the C programmers recently added a constructor for private >> keys which takes a function pointer as an argument: >> >> https://codeberg.org/io/highctidh/src/branch/main/csidh.h#L50 >> >> /* >> * generate a new private key using rng_callback and write the result to >> (priv). >> * (priv) is passed as (context) to the rng_callback. >> */ >> void csidh_private_withrng(private_key *priv, ctidh_fillrandom >> rng_callback); >> >> I did get this to work with an ugly hack where the golang constructor >> takes an io.Reader interface object as an argument and sets an unexported >> module scoped global variable to the rng/io.Reader object, guarded by a >> mutex, gross: >> >> >> https://git.xx.network/elixxir/ctidh_cgo/-/commit/2e7fb078722decb07ab8da7fb59c8ec46fb32fd1 >> >> But that's a really ugly hack and if called by multiple threads would >> result in the rng getting overwritten... which in most cases is probably >> fine for that to happen but seems like a bad design. >> >> >> >> >> -- 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/a8b5fa3e-3ff0-45f1-8864-c169d6cafa23n%40googlegroups.com.
[go-nuts] Re: cgo: how to pass an entropy source from golang to C?
Okay here I've tried a similar solution to the go-pointers library... but i had to change it a bit to fit how the C library uses the context pointer: https://git.xx.network/elixxir/ctidh_cgo/-/commit/8f02611b943c269eab5b6e888958e4d41d72cd51 It builds and runs... and then panics on the "rng is nil"... not sure why. So I'm going to try another solution where I change the C api slightly. I'm convinced there are many possible solutions to this and picking one is a matter of deciding among a few tradeoffs. On Tuesday, October 18, 2022 at 6:33:11 PM UTC-4 David Stainton wrote: > Greetings cgo experts, perhaps this post might also be of some interest to > cryptography people as well. > > What's the best way for a C cryptography library to receive entropy from > golang? > > There exists a C cryptography library (CTIDH, it's a PQ NIKE)... I am > collaborating with C programmers who are adding features to it. I maintain > cgo bindings for this library. Thus far the cgo is straight forward and it > works. However the C programmers recently added a constructor for private > keys which takes a function pointer as an argument: > > https://codeberg.org/io/highctidh/src/branch/main/csidh.h#L50 > > /* > * generate a new private key using rng_callback and write the result to > (priv). > * (priv) is passed as (context) to the rng_callback. > */ > void csidh_private_withrng(private_key *priv, ctidh_fillrandom > rng_callback); > > I did get this to work with an ugly hack where the golang constructor > takes an io.Reader interface object as an argument and sets an unexported > module scoped global variable to the rng/io.Reader object, guarded by a > mutex, gross: > > > https://git.xx.network/elixxir/ctidh_cgo/-/commit/2e7fb078722decb07ab8da7fb59c8ec46fb32fd1 > > But that's a really ugly hack and if called by multiple threads would > result in the rng getting overwritten... which in most cases is probably > fine for that to happen but seems like a bad design. > > > > > -- 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/cfcb3675-eb9a-46b6-85a8-ceaa1329c185n%40googlegroups.com.
[go-nuts] cgo: how to pass an entropy source from golang to C?
Greetings cgo experts, perhaps this post might also be of some interest to cryptography people as well. What's the best way for a C cryptography library to receive entropy from golang? There exists a C cryptography library (CTIDH, it's a PQ NIKE)... I am collaborating with C programmers who are adding features to it. I maintain cgo bindings for this library. Thus far the cgo is straight forward and it works. However the C programmers recently added a constructor for private keys which takes a function pointer as an argument: https://codeberg.org/io/highctidh/src/branch/main/csidh.h#L50 /* * generate a new private key using rng_callback and write the result to (priv). * (priv) is passed as (context) to the rng_callback. */ void csidh_private_withrng(private_key *priv, ctidh_fillrandom rng_callback); I did get this to work with an ugly hack where the golang constructor takes an io.Reader interface object as an argument and sets an unexported module scoped global variable to the rng/io.Reader object, guarded by a mutex, gross: https://git.xx.network/elixxir/ctidh_cgo/-/commit/2e7fb078722decb07ab8da7fb59c8ec46fb32fd1 But that's a really ugly hack and if called by multiple threads would result in the rng getting overwritten... which in most cases is probably fine for that to happen but seems like a bad design. -- 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/4ead4877-4225-4131-b304-82a331ddc1fan%40googlegroups.com.
Re: [go-nuts] cgo binding copies data twice, necessary?
Hi! Yes that works perfectly. I've added the bounds checking. Thanks and cheers! Sincerely, David On Tuesday, August 23, 2022 at 3:51:39 AM UTC-4 progl...@gmail.com wrote: > Assuming that `p.privateKey = *((*C.private_key)(key))` is making a full > copy, not shallow. I think you could avoid using `C.CBytes`. > > You can get the address of the start of the backing array via &data[0] as > per https://pkg.go.dev/cmd/cgo > > So maybe something like this: > p.privateKey = *((*C.private_key)(unsafe.Pointer(&data[0]))) > > The code doesn't seem that safe though. There should be something that > actually checks that the byte slice is the correct size. > > On Tue, 23 Aug 2022 at 00:41, David Stainton wrote: > >> I recently wrote cgo bindings to the CTIDH C library (a bleeding edge >> post quantum non-interactive key exchange) copies the data twice. First in >> the call to C.CBytes and then again in the assignment to p.privateKey via >> that pointer dereference. >> >> The performance hit for the twice copy is not really a problem. I'm just >> curious, is there's a more proper way to write this that avoids the twice >> copy? >> >> >> // FromBytes loads a PrivateKey from the given byte slice. >> func (p *PrivateKey) FromBytes(data []byte) { >>key := C.CBytes(data) >>defer C.free(key) >>p.privateKey = *((*C.private_key)(key)) >> } >> >> https://git.xx.network/elixxir/ctidh_cgo/-/blob/master/binding.go#L49-54 >> >> >> Sincerely, >> 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...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/3b8a9098-aabb-4b53-933e-b4e4b6e21cdcn%40googlegroups.com >> >> <https://groups.google.com/d/msgid/golang-nuts/3b8a9098-aabb-4b53-933e-b4e4b6e21cdcn%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> > -- 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/a30ff3b9-5e61-42a7-aaee-6f7f04b08168n%40googlegroups.com.
[go-nuts] cgo binding copies data twice, necessary?
I recently wrote cgo bindings to the CTIDH C library (a bleeding edge post quantum non-interactive key exchange) copies the data twice. First in the call to C.CBytes and then again in the assignment to p.privateKey via that pointer dereference. The performance hit for the twice copy is not really a problem. I'm just curious, is there's a more proper way to write this that avoids the twice copy? // FromBytes loads a PrivateKey from the given byte slice. func (p *PrivateKey) FromBytes(data []byte) { key := C.CBytes(data) defer C.free(key) p.privateKey = *((*C.private_key)(key)) } https://git.xx.network/elixxir/ctidh_cgo/-/blob/master/binding.go#L49-54 Sincerely, 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/3b8a9098-aabb-4b53-933e-b4e4b6e21cdcn%40googlegroups.com.
[go-nuts] Re: decode unknown CBOR type with set of known types
Hi, I've been informed of how exactly to use the CBOR tag solution by the author of one of the cbor.io recommended CBOR libraries: https://github.com/fxamacker/cbor/issues/241#issuecomment-656881180 This solution is clearly a bit nicer than the wrapping struct solution but it's specific to the given CBOR library whereas the wrapping struct solution would likely work with any serialization library. Not that Brian and Jonathan both suggested this solution... however it's very helpful to see this code example of how exactly to do it since it wasn't immediately obvious from reading the API docs of the various CBOR libraries. I shall quote the author's code sample herein: """ // Create TagSet with tag number and Go type tags := cbor.NewTagSet() err := tags.Add( cbor.TagOptions{EncTag: cbor.EncTagRequired, DecTag: cbor.DecTagRequired}, reflect.TypeOf(MyType{}),// your custom type MyTypeCBORTagNumber, // CBOR tag number for your custom type ) // Create decoding mode with TagSet dm, err := cbor.DecOptions{}.DecModeWithTags(tags) // Decode unknown CBOR blob var v interface{} err = dm.Unmarshal(b, &v) // Use type switch to handle different types switch v := v.(type) { case MyType: // custom type ... default: ... } """ -- 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/8ffa761a-bfec-4658-bccd-f9a5b1297991o%40googlegroups.com.
[go-nuts] Re: decode unknown CBOR type with set of known types
Hi Jonathan, Thanks for the suggestion. I'm going to take this approach of using a wrapping struct like in your example. Although it might be possible to solve this problem with CBOR tags this seems more difficult and possibly not supported by the existing go CBOR libraries. Cheers, David On Wednesday, July 8, 2020 at 9:55:26 PM UTC, Jonathan Amsterdam wrote: > > My first question would be, is the type encoded into the CBOR blob > somehow? Like by a tag? > > If structs are encoded as maps, with no type information, then the input > doesn't have enough information to do what you want. How could the blob > (using JSON notation) > >{"X": 1, "Y": 2} > > know whether it should decode into > > type Point struct { X, Y int} > > or > > type Chromosome {X, Y int} > > ? > > You have to encode the type somehow. If you control the encoding process > and you're encoding a fixed set of types that you want to distinguish at > decode time, > you can do something like this: > > type ( > This ... > That ... > TheOther ... > > Thing struct { > This *This > That *That > TheOther *TheOther > } > ) > > To encode a `This` named `t`, actually encode `Thing{This: &t}`. When you > decode that into a `Thing`, only the `This` field will be non-nil, so you > know you've got a `This`. > > (Disclaimer: I know this technique works with the encoding/json package; I > can't guarantee it works with the cbor package you're using because I'm not > familiar with it, > but if it behaves like encoding/json, you should be OK.) > > On Wednesday, July 8, 2020 at 3:44:36 PM UTC-4, David Stainton wrote: >> >> >> Greetings, >> >> Similar questions have been asked in the past and I've read those >> posts... and I believe I'm asking something different here. >> >> I'm using length prefixed CBOR over unix domain socket as my wire format. >> However the reader doesn't known which CBOR type it needs to decode. >> I'd like a mechanism similar to the golang switch type assertion where a >> known set of types are specified. >> >> Before you go and tell me to use the empty interface let me explain that >> certainly this works: >> >> // "github.com/fxamacker/cbor" >> var v interface{} >> err = cbor.Unmarshal(out, &v) >> >> It works for some definitions of "works". It doesn't tell me what type it >> is but it does allow me to access each struct field by name in the map of >> type: map[interface {}]interface {} >> >> The reason this is not good enough is that it doesn't concretely tell me >> the type! >> Of course I could go ahead and add a struct field called TypeName and set >> it's value to a string encoding the name. But that feels wrong and I'd feel >> bad after writing it. >> >> I've also tried to ask this question on a ticket here: >> https://github.com/fxamacker/cbor/issues/241 >> >> Is the least incorrect solution to iteratively try cbor.Unmarshal with >> all the types in the known set of possible types until one of them works? >> >> Certainly this problem isn't specific to CBOR. Am I asking the question >> incorrectly here? >> >> >> Sincerely, >> 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/007daae0-d5f6-442e-81fb-cd4976ddca7do%40googlegroups.com.
[go-nuts] decode unknown CBOR type with set of known types
Greetings, Similar questions have been asked in the past and I've read those posts... and I believe I'm asking something different here. I'm using length prefixed CBOR over unix domain socket as my wire format. However the reader doesn't known which CBOR type it needs to decode. I'd like a mechanism similar to the golang switch type assertion where a known set of types are specified. Before you go and tell me to use the empty interface let me explain that certainly this works: // "github.com/fxamacker/cbor" var v interface{} err = cbor.Unmarshal(out, &v) It works for some definitions of "works". It doesn't tell me what type it is but it does allow me to access each struct field by name in the map of type: map[interface {}]interface {} The reason this is not good enough is that it doesn't concretely tell me the type! Of course I could go ahead and add a struct field called TypeName and set it's value to a string encoding the name. But that feels wrong and I'd feel bad after writing it. I've also tried to ask this question on a ticket here: https://github.com/fxamacker/cbor/issues/241 Is the least incorrect solution to iteratively try cbor.Unmarshal with all the types in the known set of possible types until one of them works? Certainly this problem isn't specific to CBOR. Am I asking the question incorrectly here? Sincerely, 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/f48f6955-0478-4adf-a775-268a480dfdbfo%40googlegroups.com.