tinygo
tinygo copied to clipboard
Lacking RSA keypair capacity in Tinygo
Hi community,
Seems no crypto/cipher package in Tinygo, which is availabe in standard Golang. If so, seems we can not achieve Sign and Check feature of RSA private / public key pair with Tinygo in our WASM proxy project for proxy Envoy.
Anybody who can help to advise the workaround solution will be appreciated?
TinyGo uses the Go standard library for most packages, so crypto/rsa is available. But it might not work yet because some things might not be implemented.
Can you share the error you're getting?
I think crypto/cipher has some issues with dispatching to the specialized xorBytes implementations, or at least it did once upon a time.
@aykevl, @deadprogram @dgryski we are doing the coding.
The time being, we found crypto/rsa is able to be imported but can not pass test, on this page https://tinygo.org/docs/reference/lang-support/stdlib/#crypto.
We are confused:
- what is the meaning of yes on importable but no on passes tests?
- Does it means the runtime functionality still not work even though no compile error?
Today we have a validation on the support capacity on crypto/rsa with Tinygo. Unfortunately, as the official support description, Crypto/rsa is not supported well.
Below exception will be feed back with tinygo, while it works well with Golang.
tinygo build -o test.exe .\examples\main.go
ld.lld: error: undefined symbol: crypto/ed25519/internal/edwards25519/field.feMul
>>> referenced by main
>>> C:\Users\lewise.liu\AppData\Local\Temp\tinygo3568153588\main.o
ld.lld: error: undefined symbol: crypto/ed25519/internal/edwards25519/field.feSquare
>>> referenced by main
>>> C:\Users\lewise.liu\AppData\Local\Temp\tinygo3568153588\main.o
failed to run tool: ld.lld
error: failed to link C:\Users\lewise.liu\AppData\Local\Temp\tinygo3568153588\main.exe: exit status 1
The source code as below: https://github.com/vspaz/rsa-encrypt-decrypt-golang/
package cryptolib
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/ascii85"
"encoding/base64"
"encoding/pem"
"log"
)
type Encoder struct {
PublicKeyBlock *pem.Block
}
func NewEncoder(publicKey string) *Encoder {
publicKeyBlock, _ := pem.Decode([]byte(publicKey))
return &Encoder{
PublicKeyBlock: publicKeyBlock,
}
}
func (e *Encoder) Encrypt(text string) []byte {
encodedText := []byte(text)
var rsaPublicKey *rsa.PublicKey
pub, err := x509.ParsePKIXPublicKey(e.PublicKeyBlock.Bytes)
if err != nil {
log.Fatal("Failed to load public key")
}
rsaPublicKey = pub.(*rsa.PublicKey)
encryptedText, err := rsa.EncryptOAEP(sha1.New(), rand.Reader, rsaPublicKey, encodedText, nil)
if err != nil {
log.Fatal("Failed to encrypt text with public key")
}
return encryptedText
}
func (e Encoder) ToBase85(text []byte) string {
dest := make([]byte, ascii85.MaxEncodedLen(len(text)))
ascii85.Encode(dest, text)
return string(dest)
}
func (e Encoder) ToBase64(text []byte) string {
return base64.StdEncoding.EncodeToString(text)
}
I'll try to take a look into this.
After some patching to get the tests building under tinygo:
~/go/src/github.com/vspaz/rsa-encrypt-decrypt-golang/pkg/cryptolib $ tinygo test -target=wasi
panic: unimplemented: (reflect.Value).Addr()
Error: failed to run main module `/var/folders/5b/_hr1d1fd3qn4t9vtfx5p61wm0000gp/T/tinygo3346914303/main`
Caused by:
0: failed to invoke command default
1: wasm trap: wasm `unreachable` instruction executed
wasm backtrace:
0: 0x1efe - <unknown>!runtime._panic
1: 0x5441 - <unknown>!(reflect.Value).Addr
2: 0x777e7 - <unknown>!encoding/asn1.Unmarshal
3: 0xa8948 - <unknown>!(*github.com/vspaz/rsa-encrypt-decrypt-golang/pkg/cryptolib.Encoder).Encrypt
4: 0xac149 - <unknown>!github.com/vspaz/rsa-encrypt-decrypt-golang/pkg/cryptolib.TestRsaEncryptDecrypt
So, this is more reflect work. The link errors you observed are due to native (amd64) builds having the amd46 build tag but not (yet!) supporting the assembly routines. When built for wasi, we get the reflect issue above.
This works now, only required patching the tests to avoid the use of testify:
~/go/src/github.com/vspaz/rsa-encrypt-decrypt-golang/pkg/cryptolib $ tinygo test -target=wasi
ok github.com/vspaz/rsa-encrypt-decrypt-golang/pkg/cryptolib 0.482s
~/go/src/github.com/vspaz/rsa-encrypt-decrypt-golang/pkg/cryptolib $ git diff
diff --git a/pkg/cryptolib/encoding_decoding_test.go b/pkg/cryptolib/encoding_decoding_test.go
index b417d26..efcd02e 100644
--- a/pkg/cryptolib/encoding_decoding_test.go
+++ b/pkg/cryptolib/encoding_decoding_test.go
@@ -1,10 +1,15 @@
package cryptolib
import (
- "github.com/stretchr/testify/assert"
"testing"
)
+func assertEqual(t *testing.T, a, b string) {
+ if a != b {
+ t.Errorf("assertEqual failed: got %v, want %v", a, b)
+ }
+}
+
This is part of the v0.28 release so now closing this issue. Thanks!