tinygo
tinygo copied to clipboard
math/big: support for long arithmetic
Hello again,
According to language support page, much of the crypto functionality of Go is currently unavailable, and math/big
seems to be the culprit.
Packages like crypto/tls
also rely on net
, which I belive won't be trivial to get right due to concurrency, but the elliptic crypto packages, as well as encoding/asn1
among others, are not accessible exclusively due to one math/big
bug:
# math/big
../../../../../../../usr/local/Cellar/go/1.13.7/libexec/src/math/big/float.go:559:4: interp: branch on a non-constant
I've pulled the relevant code, but I'm yet to realise what's the branch in question. Look:
func (z *Float) SetFloat64(x float64) *Float {
if z.prec == 0 {
z.prec = 53
}
if math.IsNaN(x) {
panic(ErrNaN{"Float.SetFloat64(NaN)"})
}
z.acc = Exact
z.neg = math.Signbit(x) // handle -0, -Inf correctly
if x == 0 {
z.form = zero
return z
}
if math.IsInf(x, 0) {
z.form = inf
return z
}
// normalized x != 0
/*-->*/ z.form = finite // line 559
fmant, exp := math.Frexp(x) // get normalized mantissa
z.mant = z.mant.setUint64(1<<63 | math.Float64bits(fmant)<<11)
z.exp = int32(exp) // always fits
if z.prec < 53 {
z.round(0)
}
return z
}
I've only gone as far as to check finite
, only to realise it's a const form iota
, which is a byte-sized description of some internal representation. This code looks totally regular. Any ideas why this could go wrong? I desperately need small wasm binaries for my crypto stuff, and would love to figure this one out, but at this moment of time it's well out of my expertise.
The problem here is rather subtle and lies deep in the compiler. Last time I looked at it, I discovered that it was likely a problem with the runtime.isnil
mechanism that was needed previously (but is currently not needed anymore in LLVM 9). Also see #437.
It looks like this is going to be a blocker for Go 1.14 support. I get this error after modifying the error printer slightly while running go test
:
main.go:693: # math/rand
main.go:695: interp: branch on a non-constant
@aykevl What is the timetable on Go 1.14 support? What would you do if you were unfamiliar with the project (me, basically) and very passionate about having this resolved ASAP?
@tucnak take a look at #901. The issue with math/rand has been solved with #983, but there are a few other things left.
Looks like this can be closed?
As long as math/big
can be built...?
I believe math/big
can build and works but the tests can't run for a number of reasons:
- a lack of
encoding/gob
due toreflect
issues. -
runtime.MemStats
missingTotalAlloc
field -
interp
timeout building tests - lack of
testing/quick
support due toreflect
issues
@dgryski Now, I did a quick search around the tracker and it seems none of these issues are currently triaged. Perhaps this issue could be a reference point to get them resolved? I.e. the milestone of having full math/big
support, including (fuzzy) testing among other things. BTW, what's the maintainer's stance on fuzzing, is it fully supported tooling-wise? This is probably single most important addition to Go language since race detector! And especially important for crypto-oriented code, with much of it natively revolving around math/big
for long/modulus arithmetic. However, all the while it may be somewhat trivial to work around, what's about reflect
if you don't mind me asking? Ref. to the relevant issues should help, too!
I think https://github.com/tinygo-org/tinygo/pull/2640 is a draft of the next step in reflect support.
BTW, what's the maintainer's stance on fuzzing, is it fully supported tooling-wise? This is probably single most important addition to Go language since race detector! And especially important for crypto-oriented code, with much of it natively revolving around
math/big
for long/modulus arithmetic.
I have not yet looked into it. I guess you could simply use the go
toolchain for the fuzzing, after all, if you write portable code it should work in both TinyGo and regular Go.
Full fuzzing integration is a bunch of compiler work, not only getting the bits of of the testing package ported over. I have a very minimal randomized testing package I've used with tinygo, but note that there's no coverage guided logic or corpus support.
https://github.com/dgryski/go-tinyfuzz