I can't use a function from a library?

I have to admit I’m a beginner of golang. I write a very short program that uses functions from ibe library as follows,

package main

import (
	"fmt"
	"v.io/x/lib/ibe"
)

var Macid = "00055DNEFF"
var id string

func stringToBin(Macid string) (id string) {
	for _, c := range Macid {
		id = fmt.Sprintf("%s%b", id, c)
	}
	return id
}


func ExtractPK(id string) (pk string) {
	master, err := SetupBB1()
	pk, err := master.Extract(stringToBin(Macid))
	return
}
func main() {

	fmt.Println("MacID is " + Macid + ", public key is" + stringToBin(Macid) + ", private key is" + ExtractPK(stringToBin(Macid)))

}

But I always get the error message like

./pkg.go:5: imported and not used: “v.io/x/lib/ibe
./pkg.go:19: undefined: SetupBB1
./pkg.go:20: no new variables on left side of :=

I don’t get it. The ibe library is here. Oh my god, this kills me…please help me.

Maybe ibe.SetupBB1()?

./pkg.go:5: imported and not used: "v.io/x/lib/ibe"

This means the code in pkg.go does not use the package. In this case the next error indicates where you mean to.

./pkg.go:19: undefined: SetupBB1

The means the compiler did not find SetupBB1. I found SetupBB1 in the ibe package. The compiler did not find it because things from other packages need to be prefixed with the package name, in this case ibe.SetupBB1().

./pkg.go:20: no new variables on left side of :=

:= defines and sets the variables on its left hand side. It won’t redefine variables in the same scope (but will shadow variables from scopes higher in the stack). The line in question is:

pk, err := master.Extract(stringToBin(Macid))

pk was declared in the function signature: func ExtractPK(id string) (pk string).

err was declared on the previous line.


After fixing these errors, the next one encountered is:

./pkg.go:20: cannot assign ibe.PrivateKey to pk (type string) in multiple assignment

This happens because pk was declared as a string in the function signature, but the first value returned from from master.Extract is an ibe.PrivateKey.

How to continue depends on what you intend the program to do. As it stands, the program expects to combine the results of ExtractPK with a string, which means the result of ExtractPK must be a string. I don’t see a reason other than debugging to do this. If you really need to, use ibe.MarshalPrivateKey and convert the resulting []byte to a string.


None of the errors in this program are handled. Errors tell you when things aren’t working, and frequently can be used to figure out why and how to fix it. My preferred method is https://pocketgophers.com/error-checking-while-prototyping/ because it requires minimal thinking (allowing you to focus on the program and not the errors) and tells you the filename and line number where the error was handled.

Yes, you’re right! Thank you! I feel so stupid…:joy:

學而時習之,不亦說乎?

Oh my God, you know Chinese? I’m reading your post now, that really helps a lot. Thank you very much for your detailed information.
For this error

./pkg.go:20: cannot assign ibe.PrivateKey to pk (type string) in multiple assignment

I want to extract private key from the giving ID, so I modified my code to

func ExtractPK(id string) string {
	master, err := ibe.SetupBB1()
	PrivateKey, err := master.Extract(stringToBin(Macid))
	pk, err :=ibe.MarshalPrivateKey(PrivateKey)
	return []byte
}

Now I got

go build pkg.go
command-line-arguments
./pkg.go:22: type []byte is not an expression

Is easy to correct hopefully.

Yeah I finally got this work by

func ExtractPK(id string) (Pk string) {
	master, _ := ibe.SetupBB1()
	PrivateKey, _ := master.Extract(stringToBin(Macid))
	pkbyte, _ := ibe.MarshalPrivateKey(PrivateKey)
	n := bytes.Index(pkbyte, []byte{0})
	pk := string(pkbyte[:n])

	return pk
}

I test it for several times, and I met another error.

panic: runtime error: slice bounds out of range

goroutine 1 [running]:
main.ExtractPK(0x4211e2140, 0x41, 0x4211e2140, 0x41)
/Users/ChunjieXu/go/src/pkg/pkg.go:24 +0x141
main.main()
/Users/ChunjieXu/go/src/pkg/pkg.go:30 +0x93
exit status 2

What’s that again…A lot of things to learn…

I studied Chinese many years ago and have forgotten most of what I learned :frowning:

Please check every error. I know it can be overwhelming or seem distracting from figuring out how to get your code working, but its more frustrating when the problem could easily be found by reading the error message. My method does not require thinking about how to handle the errors, just a little bit of typing: http://pocketgophers.com/error-checking-while-prototyping/

In this case you were lucky and the problem was not hidden in an ignored error message. Instead you got a panic.

Panics always display stack traces, which tell you what line the panic was triggered on (/Users/ChunjieXu/go/src/pkg/pkg.go:24):

pk := string(pkbyte[:n])

Since the message was “slice bounds out of range” and the only slice operation on that line is pkgbyte[:n]. n comes from bytes.Index, whose documentation says:

Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.

Placing a log.Println(n, len(pkbyte)) between those two lines showed me that sometimes pkbyte does not have a []byte{0}, making n -1 and causing the panic.

Why are you searching for []byte{0}?

Your Chinese is great! If you want to pick up what you have forgotten, I’m very glad to help.

Thank you for the error-checking website. That is so helpful for me. I just need something like that.

For the slice bounds out of range, it didn’t show up when I close all the program and go build it again. I build that for more than 10 times, it was all right.

It’s just the private keys I generated each time with the same public are not the same…My professor gonna be so pissed out by the result…:joy:

子曰:「學而時習之,不亦說乎?有朋自遠方來,不亦樂乎?人不知而不慍,不亦君子乎?」

I’m glad you liked my website :blush:

The slice bounds out of range does not happen every time because SetupBB1 and Extract have random elements. My guess is that you have a background in C/C++ and expect strings to be null terminated. In Go, strings and slices have lengths associated with them and so are NOT null terminated. I am pretty sure you don’t want a subset of pkbyte.

If you professor is going to be pissed, they need to read http://crypto.stanford.edu/~dabo/papers/bbibe.pdf again (linked from the the package docs). Both the Setup and Extract phases described in §4.3 have random elements.

Hi Nathan, several days no see, how are you? Well, after some digging, I finally got this, print the private key, ciphertext and decrypted text. Do you mind helping to check if the code is what I want? Thank you.
And for the random keys problem. I digged into a little deep about this. There’s a form of key pair that the public key is (A, B,…), the private key is (C, D,…), in our case, A is like Macid and is fixed, B is some random number, and C D change everytime B changes. I think this maybe way it’s different each time.
Here’s the code.

package main

import (
	"fmt"

	"log"

	"v.io/x/lib/ibe"
)

var Macid = "00055DNEFF"

func main() {
	bb1Master, err := ibe.SetupBB1()

	if err != nil {
		log.Fatal(err)
	}

	privateKey, err := bb1Master.Extract(Macid)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("MacID is %v, private key is %v \n", Macid, privateKey)

	m := []byte("01234567899876543210123456789012")
	overhead := bb1Master.Params().CiphertextOverhead()
	C := make([]byte, len(m)+overhead)

	if err1 := bb1Master.Params().Encrypt(Macid, m, C); err1 != nil {
		log.Fatal(err1)
	}

	out := make([]byte, len(C)-overhead)

	if err2 := privateKey.Decrypt(C, out); err2 != nil {
		log.Fatal(err2)
	}

	fmt.Printf("Ciphertext is : %v \n", C)
	fmt.Printf("Decrypted text is : %v", out)

}

I’m ok, I guess…

Assuming the program generally does what you want, the only thing I see that may not be what you expect is printing the private key.

The way you printed it prints a representation of the data structure. I think you wanted the marshaled form (i.e., the key itself, not the thing needed to make the key useful):

	marshalledPrivateKey, err := ibe.MarshalPrivateKey(privateKey)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("private key:", marshalledPrivateKey)

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.