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/gobdue toreflectissues. runtime.MemStatsmissingTotalAllocfieldinterptimeout building tests- lack of
testing/quicksupport due toreflectissues
@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/bigfor 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