go icon indicating copy to clipboard operation
go copied to clipboard

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

Open rwiteshbera opened this issue 2 years ago • 4 comments

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

rwiteshbera avatar Dec 21 '22 07:12 rwiteshbera

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 avatar Dec 21 '22 19:12 dr2chase

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/

robpike avatar Dec 22 '22 00:12 robpike

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.

rwiteshbera avatar Dec 22 '22 05:12 rwiteshbera

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.

rittneje avatar Dec 22 '22 06:12 rittneje

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.

seankhliao avatar Dec 26 '22 12:12 seankhliao

Is there no equivalent substitute in the latest version?

zweix123 avatar May 22 '23 09:05 zweix123

Is there no equivalent substitute in the latest version?

No!

mkohlhaas avatar Aug 14 '23 21:08 mkohlhaas

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)
	}
}

facundocarballo avatar Jan 18 '24 19:01 facundocarballo

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)
}

smhmayboudi avatar May 02 '24 06:05 smhmayboudi