diff --git a/compiler/natives/src/crypto/ecdh/nist.go b/compiler/natives/src/crypto/ecdh/nist.go new file mode 100644 index 000000000..ecaa84d76 --- /dev/null +++ b/compiler/natives/src/crypto/ecdh/nist.go @@ -0,0 +1,58 @@ +//go:build js +// +build js + +package ecdh + +import ( + "crypto/internal/nistec" + "io" +) + +//gopherjs:purge for go1.20 without generics +type nistPoint[T any] interface{} + +// temporarily replacement of `nistCurve[Point nistPoint[Point]]` for go1.20 without generics. +type nistCurve struct { + name string + newPoint func() nistec.WrappedPoint + scalarOrder []byte +} + +//gopherjs:override-signature +func (c *nistCurve) String() string + +//gopherjs:override-signature +func (c *nistCurve) GenerateKey(rand io.Reader) (*PrivateKey, error) + +//gopherjs:override-signature +func (c *nistCurve) NewPrivateKey(key []byte) (*PrivateKey, error) + +//gopherjs:override-signature +func (c *nistCurve) privateKeyToPublicKey(key *PrivateKey) *PublicKey + +//gopherjs:override-signature +func (c *nistCurve) NewPublicKey(key []byte) (*PublicKey, error) + +//gopherjs:override-signature +func (c *nistCurve) ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error) + +// temporarily replacement for go1.20 without generics. +var p256 = &nistCurve{ + name: "P-256", + newPoint: nistec.NewP256WrappedPoint, + scalarOrder: p256Order, +} + +// temporarily replacement for go1.20 without generics. +var p384 = &nistCurve{ + name: "P-384", + newPoint: nistec.NewP384WrappedPoint, + scalarOrder: p384Order, +} + +// temporarily replacement for go1.20 without generics. +var p521 = &nistCurve{ + name: "P-521", + newPoint: nistec.NewP521WrappedPoint, + scalarOrder: p521Order, +} diff --git a/compiler/natives/src/crypto/ecdsa/ecdsa.go b/compiler/natives/src/crypto/ecdsa/ecdsa.go new file mode 100644 index 000000000..cf3da4ec8 --- /dev/null +++ b/compiler/natives/src/crypto/ecdsa/ecdsa.go @@ -0,0 +1,98 @@ +//go:build js +// +build js + +package ecdsa + +import ( + "crypto/elliptic" + "crypto/internal/bigmod" + "crypto/internal/nistec" + "io" + "math/big" +) + +//gopherjs:override-signature +func generateNISTEC(c *nistCurve, rand io.Reader) (*PrivateKey, error) + +//gopherjs:override-signature +func randomPoint(c *nistCurve, rand io.Reader) (k *bigmod.Nat, p nistec.WrappedPoint, err error) + +//gopherjs:override-signature +func signNISTEC(c *nistCurve, priv *PrivateKey, csprng io.Reader, hash []byte) (sig []byte, err error) + +//gopherjs:override-signature +func inverse(c *nistCurve, kInv, k *bigmod.Nat) + +//gopherjs:override-signature +func hashToNat(c *nistCurve, e *bigmod.Nat, hash []byte) + +//gopherjs:override-signature +func verifyNISTEC(c *nistCurve, pub *PublicKey, hash, sig []byte) bool + +//gopherjs:purge for go1.20 without generics +type nistPoint[T any] interface{} + +// temporarily replacement of `nistCurve[Point nistPoint[Point]]` for go1.20 without generics. +type nistCurve struct { + newPoint func() nistec.WrappedPoint + curve elliptic.Curve + N *bigmod.Modulus + nMinus2 []byte +} + +//gopherjs:override-signature +func (curve *nistCurve) pointFromAffine(x, y *big.Int) (p nistec.WrappedPoint, err error) + +//gopherjs:override-signature +func (curve *nistCurve) pointToAffine(p nistec.WrappedPoint) (x, y *big.Int, err error) + +var _p224 *nistCurve + +func p224() *nistCurve { + p224Once.Do(func() { + _p224 = &nistCurve{ + newPoint: nistec.NewP224WrappedPoint, + } + precomputeParams(_p224, elliptic.P224()) + }) + return _p224 +} + +var _p256 *nistCurve + +func p256() *nistCurve { + p256Once.Do(func() { + _p256 = &nistCurve{ + newPoint: nistec.NewP256WrappedPoint, + } + precomputeParams(_p256, elliptic.P256()) + }) + return _p256 +} + +var _p384 *nistCurve + +func p384() *nistCurve { + p384Once.Do(func() { + _p384 = &nistCurve{ + newPoint: nistec.NewP384WrappedPoint, + } + precomputeParams(_p384, elliptic.P384()) + }) + return _p384 +} + +var _p521 *nistCurve + +func p521() *nistCurve { + p521Once.Do(func() { + _p521 = &nistCurve{ + newPoint: nistec.NewP521WrappedPoint, + } + precomputeParams(_p521, elliptic.P521()) + }) + return _p521 +} + +//gopherjs:override-signature +func precomputeParams(c *nistCurve, curve elliptic.Curve) diff --git a/compiler/natives/src/crypto/ecdsa/ecdsa_test.go b/compiler/natives/src/crypto/ecdsa/ecdsa_test.go new file mode 100644 index 000000000..efb4d7b5e --- /dev/null +++ b/compiler/natives/src/crypto/ecdsa/ecdsa_test.go @@ -0,0 +1,12 @@ +//go:build js +// +build js + +package ecdsa + +import "testing" + +//gopherjs:override-signature +func testRandomPoint(t *testing.T, c *nistCurve) + +//gopherjs:override-signature +func testHashToNat(t *testing.T, c *nistCurve) diff --git a/compiler/natives/src/crypto/internal/boring/bcache/cache.go b/compiler/natives/src/crypto/internal/boring/bcache/cache.go index afff404ce..4c4e0dab6 100644 --- a/compiler/natives/src/crypto/internal/boring/bcache/cache.go +++ b/compiler/natives/src/crypto/internal/boring/bcache/cache.go @@ -20,6 +20,9 @@ func (c *Cache) Put(k, v unsafe.Pointer) {} //gopherjs:purge func (c *Cache) table() *[cacheSize]unsafe.Pointer +//gopherjs:purge +type cacheTable struct{} + //gopherjs:purge type cacheEntry struct{} diff --git a/compiler/natives/src/crypto/internal/boring/bcache/cache_test.go b/compiler/natives/src/crypto/internal/boring/bcache/cache_test.go index 12f2c4da4..a23e975a0 100644 --- a/compiler/natives/src/crypto/internal/boring/bcache/cache_test.go +++ b/compiler/natives/src/crypto/internal/boring/bcache/cache_test.go @@ -5,6 +5,8 @@ package bcache import "testing" +var registeredCache Cache + func TestCache(t *testing.T) { t.Skip(`This test uses runtime.GC(), which GopherJS doesn't support`) } diff --git a/compiler/natives/src/crypto/internal/nistec/nistec_test.go b/compiler/natives/src/crypto/internal/nistec/nistec_test.go index d755e7ec3..ea91d7ed2 100644 --- a/compiler/natives/src/crypto/internal/nistec/nistec_test.go +++ b/compiler/natives/src/crypto/internal/nistec/nistec_test.go @@ -18,52 +18,52 @@ type nistPoint[T any] interface{} func TestEquivalents(t *testing.T) { t.Run("P224", func(t *testing.T) { - testEquivalents(t, nistec.NewP224WrappedPoint, nistec.NewP224WrappedGenerator, elliptic.P224()) + testEquivalents(t, nistec.NewP224WrappedPoint, elliptic.P224()) }) t.Run("P256", func(t *testing.T) { - testEquivalents(t, nistec.NewP256WrappedPoint, nistec.NewP256WrappedGenerator, elliptic.P256()) + testEquivalents(t, nistec.NewP256WrappedPoint, elliptic.P256()) }) t.Run("P384", func(t *testing.T) { - testEquivalents(t, nistec.NewP384WrappedPoint, nistec.NewP384WrappedGenerator, elliptic.P384()) + testEquivalents(t, nistec.NewP384WrappedPoint, elliptic.P384()) }) t.Run("P521", func(t *testing.T) { - testEquivalents(t, nistec.NewP521WrappedPoint, nistec.NewP521WrappedGenerator, elliptic.P521()) + testEquivalents(t, nistec.NewP521WrappedPoint, elliptic.P521()) }) } //gopherjs:override-signature -func testEquivalents(t *testing.T, newPoint, newGenerator func() nistec.WrappedPoint, c elliptic.Curve) +func testEquivalents(t *testing.T, newPoint func() nistec.WrappedPoint, c elliptic.Curve) func TestScalarMult(t *testing.T) { t.Run("P224", func(t *testing.T) { - testScalarMult(t, nistec.NewP224WrappedPoint, nistec.NewP224WrappedGenerator, elliptic.P224()) + testScalarMult(t, nistec.NewP224WrappedPoint, elliptic.P224()) }) t.Run("P256", func(t *testing.T) { - testScalarMult(t, nistec.NewP256WrappedPoint, nistec.NewP256WrappedGenerator, elliptic.P256()) + testScalarMult(t, nistec.NewP256WrappedPoint, elliptic.P256()) }) t.Run("P384", func(t *testing.T) { - testScalarMult(t, nistec.NewP384WrappedPoint, nistec.NewP384WrappedGenerator, elliptic.P384()) + testScalarMult(t, nistec.NewP384WrappedPoint, elliptic.P384()) }) t.Run("P521", func(t *testing.T) { - testScalarMult(t, nistec.NewP521WrappedPoint, nistec.NewP521WrappedGenerator, elliptic.P521()) + testScalarMult(t, nistec.NewP521WrappedPoint, elliptic.P521()) }) } //gopherjs:override-signature -func testScalarMult(t *testing.T, newPoint, newGenerator func() nistec.WrappedPoint, c elliptic.Curve) +func testScalarMult(t *testing.T, newPoint func() nistec.WrappedPoint, c elliptic.Curve) func BenchmarkScalarMult(b *testing.B) { b.Run("P224", func(b *testing.B) { - benchmarkScalarMult(b, nistec.NewP224WrappedGenerator(), 28) + benchmarkScalarMult(b, nistec.NewP224WrappedPoint().SetGenerator(), 28) }) b.Run("P256", func(b *testing.B) { - benchmarkScalarMult(b, nistec.NewP256WrappedGenerator(), 32) + benchmarkScalarMult(b, nistec.NewP256WrappedPoint().SetGenerator(), 32) }) b.Run("P384", func(b *testing.B) { - benchmarkScalarMult(b, nistec.NewP384WrappedGenerator(), 48) + benchmarkScalarMult(b, nistec.NewP384WrappedPoint().SetGenerator(), 48) }) b.Run("P521", func(b *testing.B) { - benchmarkScalarMult(b, nistec.NewP521WrappedGenerator(), 66) + benchmarkScalarMult(b, nistec.NewP521WrappedPoint().SetGenerator(), 66) }) } @@ -72,16 +72,16 @@ func benchmarkScalarMult(b *testing.B, p nistec.WrappedPoint, scalarSize int) func BenchmarkScalarBaseMult(b *testing.B) { b.Run("P224", func(b *testing.B) { - benchmarkScalarBaseMult(b, nistec.NewP224WrappedGenerator(), 28) + benchmarkScalarBaseMult(b, nistec.NewP224WrappedPoint().SetGenerator(), 28) }) b.Run("P256", func(b *testing.B) { - benchmarkScalarBaseMult(b, nistec.NewP256WrappedGenerator(), 32) + benchmarkScalarBaseMult(b, nistec.NewP256WrappedPoint().SetGenerator(), 32) }) b.Run("P384", func(b *testing.B) { - benchmarkScalarBaseMult(b, nistec.NewP384WrappedGenerator(), 48) + benchmarkScalarBaseMult(b, nistec.NewP384WrappedPoint().SetGenerator(), 48) }) b.Run("P521", func(b *testing.B) { - benchmarkScalarBaseMult(b, nistec.NewP521WrappedGenerator(), 66) + benchmarkScalarBaseMult(b, nistec.NewP521WrappedPoint().SetGenerator(), 66) }) } diff --git a/compiler/natives/src/crypto/internal/nistec/wrapper.go b/compiler/natives/src/crypto/internal/nistec/wrapper.go index 0d6706b52..afa2b7049 100644 --- a/compiler/natives/src/crypto/internal/nistec/wrapper.go +++ b/compiler/natives/src/crypto/internal/nistec/wrapper.go @@ -3,8 +3,11 @@ package nistec +// temporarily replacement of `nistPoint[T any]` for go1.20 without generics. type WrappedPoint interface { + SetGenerator() WrappedPoint Bytes() []byte + BytesX() ([]byte, error) SetBytes(b []byte) (WrappedPoint, error) Add(w1, w2 WrappedPoint) WrappedPoint Double(w1 WrappedPoint) WrappedPoint @@ -24,14 +27,18 @@ func NewP224WrappedPoint() WrappedPoint { return wrapP224(NewP224Point()) } -func NewP224WrappedGenerator() WrappedPoint { - return wrapP224(NewP224Generator()) +func (w p224Wrapper) SetGenerator() WrappedPoint { + return wrapP224(w.point.SetGenerator()) } func (w p224Wrapper) Bytes() []byte { return w.point.Bytes() } +func (w p224Wrapper) BytesX() ([]byte, error) { + return w.point.BytesX() +} + func (w p224Wrapper) SetBytes(b []byte) (WrappedPoint, error) { p, err := w.point.SetBytes(b) return wrapP224(p), err @@ -67,14 +74,18 @@ func NewP256WrappedPoint() WrappedPoint { return wrapP256(NewP256Point()) } -func NewP256WrappedGenerator() WrappedPoint { - return wrapP256(NewP256Generator()) +func (w p256Wrapper) SetGenerator() WrappedPoint { + return wrapP256(w.point.SetGenerator()) } func (w p256Wrapper) Bytes() []byte { return w.point.Bytes() } +func (w p256Wrapper) BytesX() ([]byte, error) { + return w.point.BytesX() +} + func (w p256Wrapper) SetBytes(b []byte) (WrappedPoint, error) { p, err := w.point.SetBytes(b) return wrapP256(p), err @@ -110,14 +121,18 @@ func NewP521WrappedPoint() WrappedPoint { return wrapP521(NewP521Point()) } -func NewP521WrappedGenerator() WrappedPoint { - return wrapP521(NewP521Generator()) +func (w p521Wrapper) SetGenerator() WrappedPoint { + return wrapP521(w.point.SetGenerator()) } func (w p521Wrapper) Bytes() []byte { return w.point.Bytes() } +func (w p521Wrapper) BytesX() ([]byte, error) { + return w.point.BytesX() +} + func (w p521Wrapper) SetBytes(b []byte) (WrappedPoint, error) { p, err := w.point.SetBytes(b) return wrapP521(p), err @@ -153,14 +168,18 @@ func NewP384WrappedPoint() WrappedPoint { return wrapP384(NewP384Point()) } -func NewP384WrappedGenerator() WrappedPoint { - return wrapP384(NewP384Generator()) +func (w p384Wrapper) SetGenerator() WrappedPoint { + return wrapP384(w.point.SetGenerator()) } func (w p384Wrapper) Bytes() []byte { return w.point.Bytes() } +func (w p384Wrapper) BytesX() ([]byte, error) { + return w.point.BytesX() +} + func (w p384Wrapper) SetBytes(b []byte) (WrappedPoint, error) { p, err := w.point.SetBytes(b) return wrapP384(p), err