Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/gob: type not registered for interface: elliptic.p256Curve #57422

Closed
rwiteshbera opened this issue Dec 21, 2022 · 9 comments
Closed
Labels
WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.

Comments

@rwiteshbera
Copy link

rwiteshbera commented Dec 21, 2022

func (w *Data) SaveFile() {
    var content bytes.Buffer

    gob.Register(elliptic.P256())
    encoder := gob.NewEncoder(&content)

    if err := encoder.Encode(w); err != nil {
        log.Panic(err)
    }

    fmt.Println(content)
}

Error

gob: type not registered for interface: elliptic.p256Curve

What version of Go are you using (go version)?

$ go version
1.19.3
@dr2chase dr2chase changed the title affected/package: gob: type not registered for interface: elliptic.p256Curve gob: type not registered for interface: elliptic.p256Curve Dec 21, 2022
@dr2chase dr2chase changed the title gob: type not registered for interface: elliptic.p256Curve encoding/gob: type not registered for interface: elliptic.p256Curve Dec 21, 2022
@dr2chase
Copy link
Contributor

A runnable example would be very helpful; without more context, I can't tell much about what's supposed to happen. What did you expect to happen?

@dr2chase dr2chase added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Dec 21, 2022
@robpike
Copy link
Contributor

robpike commented Dec 22, 2022

elliptic.P256 is a function, not an interface, so registering it is meaningless. If anything, you want to register elliptic.Curve, I think.

However, @dr2chase is right: without a complete runnable example with import statements and main function, it's hard to diagnose any problem.

https://www.softwaretestinghelp.com/how-to-write-good-bug-report/

@rwiteshbera
Copy link
Author

type Wallet struct {
	PrivateKey    *ecdsa.PrivateKey
	PublicKey     *ecdsa.PublicKey
	WalletAddress string
}

type Wallets struct {
	Wallets map[string]*Wallet
}

I want to encode the type Wallets struct data and store it in a data.gob file.

Here is my code

func (w *Wallets) SaveFile() {
    var content bytes.Buffer

    gob.Register(elliptic.P256())
    encoder := gob.NewEncoder(&content)

    if err := encoder.Encode(w); err != nil {
        log.Panic(err)
    }

    fmt.Println(content)
}

The gob package failed to encode as it is showing the error gob: type not registered for interface: elliptic.p256Curve

How can I encode a type Wallets struct that contents Wallets mapping (string->Wallet) ?

gob package is not working and I'm not able to find any working solution.

@rittneje
Copy link

I get a different error from this: "gob: type elliptic.p256Curve has no exported fields". https://go.dev/play/p/koZfJIH_lOl

However, the same code works in 1.18. The discrepancy is due to elliptic.p256Curve switching from embedding *elliptic.CurveParams in 1.18 to embedding elliptic.nistCurve in 1.19. Evidently, this was technically a breaking change.

@seankhliao
Copy link
Member

As an unexported type, this change was one allowed by the stdlib.

Note that crypto/elliptic has specialized functions for marshaling and unmarshaling key data, you should be using those rather than on hidden implementation details.

Closing as unfortunate, but working as intended.

@zweix123
Copy link

Is there no equivalent substitute in the latest version?

@mkohlhaas
Copy link

Is there no equivalent substitute in the latest version?

No!

@facundocarballo
Copy link

Maybe this would help. I was getting the same issue because I wanna encode a Wallets structure (that uses this interface of P256 Elliptic Curve) with a buffer and this gob.NewEncoder.

What I did to work me, it's change the way that I was trying to encode this structure. So I encode the structure with json.Marshal instead of the bytes.Buffer and this gob.NewEncoder.

Old Code (With troubles)

func (ws *Wallets) SaveFile() {
	var content bytes.Buffer

	gob.Register(elliptic.P256())

	encoder := gob.NewEncoder(&content)
	err := encoder.Encode(ws) // HERE WAS THE PROBLEM
	if err != nil {
		log.Panic(err)
	}

	err = ioutil.WriteFile(walletFile, content.Bytes(), 0644)
	if err != nil {
		log.Panic(err)
	}
}

New Code (Working)

func (ws *Wallets) SaveFile() {
	jsonData, err := json.Marshal(ws)
	handlers.HandleErrors(err)

	err = ioutil.WriteFile(walletFile, jsonData, 0544)
	handlers.HandleErrors(err)
}

Helpers Module

package handlers

import "log"

func HandleErrors(err error) {
	if err != nil {
		log.Panic(err)
	}
}

@smhmayboudi
Copy link

in addition to the previous answer we should apply some more code as well.
@rwiteshbera @facundocarballo

// wallet.go
func (w Wallet) MarshalJSON() ([]byte, error) {
	mapStringAny := map[string]any{
		"PrivateKey": map[string]any{
			"D": w.PrivateKey.D,
			"PublicKey": map[string]any{
				"X": w.PrivateKey.PublicKey.X,
				"Y": w.PrivateKey.PublicKey.Y,
			},
			"X": w.PrivateKey.X,
			"Y": w.PrivateKey.Y,
		},
		"PublicKey": w.PublicKey,
	}
	return json.Marshal(mapStringAny)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

9 participants