[go-nuts] Re: CBOR / pq cryptography migration / software architecture golang question

2023-02-10 Thread David Stainton
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

2023-02-10 Thread David Stainton

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?

2022-12-03 Thread David Stainton
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?

2022-12-03 Thread David Stainton
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?

2022-10-19 Thread David Stainton
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?

2022-10-18 Thread David Stainton

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?

2022-10-18 Thread David Stainton
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?

2022-08-23 Thread David Stainton
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?

2022-08-22 Thread David Stainton
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

2020-07-10 Thread David Stainton

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

2020-07-09 Thread David Stainton

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

2020-07-08 Thread David Stainton

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.