diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bb75db57c..6974918f0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,6 +37,3 @@ jobs: - name: Build Linux run: GOOS=linux GOARCH=${{ matrix.goarch }} CC=${{ matrix.gcc }} TARGET_HOST=${{ matrix.host }} make build if: "env.GIT_DIFF != ''" - - name: Build Linux with Libsodium - run: GOOS=linux GOARCH=${{ matrix.goarch }} CC=${{ matrix.gcc }} TARGET_HOST=${{ matrix.host }} LIBSODIUM=1 make build - if: "env.GIT_DIFF != ''" diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index dd4fb9df3..71382516a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -38,55 +38,6 @@ jobs: name: "${{ github.sha }}-05" path: ./pkgs.txt.part.05 - build-libsodium: - name: Build libsodium - runs-on: ubuntu-latest - needs: split-test-files - steps: - - uses: actions/checkout@v3 - - run: make libsodium - - uses: actions/upload-artifact@v3 - with: - name: libsodium - path: crypto/vrf/internal/vrf/sodium - - tests: - runs-on: ubuntu-latest - needs: build-libsodium - strategy: - fail-fast: false - matrix: - vrf: ["r2ishiguro", "libsodium"] - part: ["00", "01", "02", "03", "04", "05"] - steps: - - uses: actions/setup-go@v4 - with: - go-version: '1.18' - - uses: actions/checkout@v3 - - uses: technote-space/get-diff-action@v6.1.2 - with: - PATTERNS: | - **/**.go - go.mod - go.sum - Makefile - - uses: actions/download-artifact@v3 - with: - name: "${{ github.sha }}-${{ matrix.part }}" - if: env.GIT_DIFF - - uses: actions/download-artifact@v3 - with: - name: libsodium - path: crypto/vrf/internal/vrf/sodium - - name: test & coverage report creation - run: | - cat pkgs.txt.part.${{ matrix.part }} | xargs go test -mod=readonly -timeout 7m -race -coverprofile=${{ matrix.part }}profile.out -covermode=atomic -tags ${{ matrix.vrf }} - if: env.GIT_DIFF - - uses: actions/upload-artifact@v3 - with: - name: "${{ github.sha }}-${{ matrix.part }}-coverage" - path: ./${{ matrix.part }}profile.out - upload-coverage-report: runs-on: ubuntu-latest needs: tests diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index cc64de0ad..21de58f1b 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -122,9 +122,6 @@ jobs: docker load -i ${{ needs.e2e-build.outputs.CACHE_FILE }} if: "env.GIT_DIFF != ''" - - name: Build libsodium - run: make libsodium - - name: Build e2e runner working-directory: test/e2e run: make runner diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index ac9144cbe..000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "crypto/vrf/internal/vrf/libsodium"] - path = crypto/vrf/internal/vrf/libsodium - url = https://github.com/algorand/libsodium.git diff --git a/Makefile b/Makefile index 94021efcd..b4ddd1255 100644 --- a/Makefile +++ b/Makefile @@ -5,13 +5,6 @@ OUTPUT?=build/ostracon INCLUDE = -I=${GOPATH}/src/github.com/Finschia/ostracon -I=${GOPATH}/src -I=${GOPATH}/src/github.com/gogo/protobuf/protobuf BUILD_TAGS ?= ostracon VERSION := $(shell git describe --always) -ifeq ($(LIBSODIUM), 1) - BUILD_TAGS += libsodium - LIBSODIUM_TARGET = libsodium -else - BUILD_TAGS += r2ishiguro - LIBSODIUM_TARGET = -endif LD_FLAGS = -X github.com/Finschia/ostracon/version.OCCoreSemVer=$(VERSION) BUILD_FLAGS = -mod=readonly -ldflags "$(LD_FLAGS)" HTTPS_GIT := https://github.com/Finschia/ostracon.git @@ -64,11 +57,11 @@ include tests.mk ### Build Ostracon ### ############################################################################### -build: $(LIBSODIUM_TARGET) +build: CGO_ENABLED=1 go build $(BUILD_FLAGS) -tags "$(BUILD_TAGS)" -o $(OUTPUT) ./cmd/ostracon/ .PHONY: build -install: $(LIBSODIUM_TARGET) +install: CGO_ENABLED=1 go install $(BUILD_FLAGS) -tags "$(BUILD_TAGS)" ./cmd/ostracon .PHONY: install @@ -268,7 +261,7 @@ DOCKER_CMD = docker run --rm \ DOCKER_IMG = golang:1.18-alpine BUILD_CMD = apk add --update --no-cache git make gcc libc-dev build-base curl jq bash file gmp-dev clang libtool autoconf automake \ && cd $(DOCKER_HOME) \ - && LIBSODIUM=$(LIBSODIUM) make build-linux + && make build-linux # Login docker-container for confirmation building linux binary build-shell: diff --git a/crypto/crypto.go b/crypto/crypto.go index 6d35a4549..49e1cb1d4 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -28,7 +28,7 @@ type PubKey interface { Address() Address Bytes() []byte VerifySignature(msg []byte, sig []byte) bool - VRFVerify(proof []byte, seed []byte) (Output, error) // TODO 🏺 rename to VerifyVRFProof to match VerifySignature + VRFVerify(proof []byte, message []byte) (Output, error) Equals(PubKey) bool Type() string } diff --git a/crypto/ed25519/vrf_test.go b/crypto/ed25519/vrf_test.go new file mode 100644 index 000000000..ec34d5f26 --- /dev/null +++ b/crypto/ed25519/vrf_test.go @@ -0,0 +1,133 @@ +package ed25519 + +import ( + "bytes" + "io" + "testing" + + "github.com/Finschia/ostracon/crypto/internal/testhelpers" + "github.com/oasisprotocol/curve25519-voi/primitives/ed25519" + "github.com/oasisprotocol/curve25519-voi/primitives/ed25519/extra/ecvrf" +) + +func TestECVRF(t *testing.T) { + t.Run("TestVectors", testIETFVectors) +} + +// This test vector follows this value of irtf (A.4. ECVRF-EDWARDS25519-SHA512-ELL2). +// Please refer to this URL for details. +// http://www.watersprings.org/pub/id/draft-irtf-cfrg-vrf-07.html#rfc.appendix.A.4 +func testIETFVectors(t *testing.T) { + testVectors := []struct { + sk []byte + pk []byte + alpha []byte + pi []byte + beta []byte + v10 bool + }{ + // Old (v10 and prior) semantics + { + sk: testhelpers.MustUnhex(t, "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"), + pk: testhelpers.MustUnhex(t, "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"), + alpha: []byte{}, + pi: testhelpers.MustUnhex(t, "7d9c633ffeee27349264cf5c667579fc583b4bda63ab71d001f89c10003ab46f25898f6bd7d4ed4c75f0282b0f7bb9d0e61b387b76db60b3cbf34bf09109ccb33fab742a8bddc0c8ba3caf5c0b75bb04"), + beta: testhelpers.MustUnhex(t, "9d574bf9b8302ec0fc1e21c3ec5368269527b87b462ce36dab2d14ccf80c53cccf6758f058c5b1c856b116388152bbe509ee3b9ecfe63d93c3b4346c1fbc6c54"), + v10: true, + }, + { + sk: testhelpers.MustUnhex(t, "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb"), + pk: testhelpers.MustUnhex(t, "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"), + alpha: []byte{0x72}, + pi: testhelpers.MustUnhex(t, "47b327393ff2dd81336f8a2ef10339112401253b3c714eeda879f12c509072ef9bf1a234f833f72d8fff36075fd9b836da28b5569e74caa418bae7ef521f2ddd35f5727d271ecc70b4a83c1fc8ebc40c"), + beta: testhelpers.MustUnhex(t, "38561d6b77b71d30eb97a062168ae12b667ce5c28caccdf76bc88e093e4635987cd96814ce55b4689b3dd2947f80e59aac7b7675f8083865b46c89b2ce9cc735"), + v10: true, + }, + { + sk: testhelpers.MustUnhex(t, "c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7"), + pk: testhelpers.MustUnhex(t, "fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025"), + alpha: []byte{0xaf, 0x82}, + pi: testhelpers.MustUnhex(t, "926e895d308f5e328e7aa159c06eddbe56d06846abf5d98c2512235eaa57fdce6187befa109606682503b3a1424f0f729ca0418099fbd86a48093e6a8de26307b8d93e02da927e6dd5b73c8f119aee0f"), + beta: testhelpers.MustUnhex(t, "121b7f9b9aaaa29099fc04a94ba52784d44eac976dd1a3cca458733be5cd090a7b5fbd148444f17f8daf1fb55cb04b1ae85a626e30a54b4b0f8abf4a43314a58"), + v10: true, + }, + // New (v11 and latter) semantics + { + sk: testhelpers.MustUnhex(t, "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"), + pk: testhelpers.MustUnhex(t, "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"), + alpha: []byte{}, + pi: testhelpers.MustUnhex(t, "7d9c633ffeee27349264cf5c667579fc583b4bda63ab71d001f89c10003ab46f14adf9a3cd8b8412d9038531e865c341cafa73589b023d14311c331a9ad15ff2fb37831e00f0acaa6d73bc9997b06501"), + beta: testhelpers.MustUnhex(t, "9d574bf9b8302ec0fc1e21c3ec5368269527b87b462ce36dab2d14ccf80c53cccf6758f058c5b1c856b116388152bbe509ee3b9ecfe63d93c3b4346c1fbc6c54"), + }, + { + sk: testhelpers.MustUnhex(t, "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb"), + pk: testhelpers.MustUnhex(t, "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"), + alpha: []byte{0x72}, + pi: testhelpers.MustUnhex(t, "47b327393ff2dd81336f8a2ef10339112401253b3c714eeda879f12c509072ef055b48372bb82efbdce8e10c8cb9a2f9d60e93908f93df1623ad78a86a028d6bc064dbfc75a6a57379ef855dc6733801"), + beta: testhelpers.MustUnhex(t, "38561d6b77b71d30eb97a062168ae12b667ce5c28caccdf76bc88e093e4635987cd96814ce55b4689b3dd2947f80e59aac7b7675f8083865b46c89b2ce9cc735"), + }, + { + sk: testhelpers.MustUnhex(t, "c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7"), + pk: testhelpers.MustUnhex(t, "fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025"), + alpha: []byte{0xaf, 0x82}, + pi: testhelpers.MustUnhex(t, "926e895d308f5e328e7aa159c06eddbe56d06846abf5d98c2512235eaa57fdce35b46edfc655bc828d44ad09d1150f31374e7ef73027e14760d42e77341fe05467bb286cc2c9d7fde29120a0b2320d04"), + beta: testhelpers.MustUnhex(t, "121b7f9b9aaaa29099fc04a94ba52784d44eac976dd1a3cca458733be5cd090a7b5fbd148444f17f8daf1fb55cb04b1ae85a626e30a54b4b0f8abf4a43314a58"), + }, + } + for i, vec := range testVectors { + sk := ed25519.NewKeyFromSeed(vec.sk) + pk := sk.Public().(ed25519.PublicKey) + + var ( + proveFn func(ed25519.PrivateKey, []byte) []byte + verifyFn func(ed25519.PublicKey, []byte, []byte) (bool, []byte) + proveRandFn func(io.Reader, ed25519.PrivateKey, []byte) ([]byte, error) + ) + switch vec.v10 { + case false: + proveFn = ecvrf.Prove + verifyFn = ecvrf.Verify + proveRandFn = ecvrf.ProveWithAddedRandomness + case true: + proveFn = ecvrf.Prove_v10 + verifyFn = ecvrf.Verify_v10 + proveRandFn = ecvrf.ProveWithAddedRandomness_v10 + } + + pi := proveFn(sk, vec.alpha) + if !bytes.Equal(vec.pi, pi) { + t.Fatalf("[%d] pi mismatch (Got: %x)", i, pi) + } + + ok, beta := verifyFn(pk, pi, vec.alpha) + if !ok { + t.Fatalf("[%d] Verify() failed", i) + } + if !bytes.Equal(vec.beta, beta) { + t.Fatalf("[%d] beta mismatch (Got: %x)", i, beta) + } + + // Test that adding entropy to the signing process produces + // different pi, but identical beta. + piNonDeterministic, err := proveRandFn(nil, sk, vec.alpha) + if err != nil { + t.Fatalf("[%d] ProveWithAddedRandomness(): %v", i, err) + } + if bytes.Equal(piNonDeterministic, pi) { + t.Fatalf("[%d] pi (non-determinstic) matched (Got: %x)", i, piNonDeterministic) + } + ok, beta = verifyFn(pk, piNonDeterministic, vec.alpha) + if !ok { + t.Fatalf("[%d] Verify(pi_non_deterministic) failed", i) + } + if !bytes.Equal(vec.beta, beta) { + t.Fatalf("[%d] beta (non-determinstic pi) mismatch (Got: %x)", i, beta) + } + + pi[0] ^= 0xa5 + ok, _ = verifyFn(pk, pi, vec.alpha) + if ok { + t.Fatalf("[%d] bad pi, Verify() passed", i) + } + } +} diff --git a/crypto/internal/testhelpers/helpers.go b/crypto/internal/testhelpers/helpers.go index 1a5c5084a..61ec82ea0 100644 --- a/crypto/internal/testhelpers/helpers.go +++ b/crypto/internal/testhelpers/helpers.go @@ -1,32 +1,3 @@ -// Copyright (c) 2021 Oasis Labs Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - package testhelpers import ( diff --git a/crypto/secp256k1/secp256k1.go b/crypto/secp256k1/secp256k1.go index a4e3587eb..bf35bcab0 100644 --- a/crypto/secp256k1/secp256k1.go +++ b/crypto/secp256k1/secp256k1.go @@ -187,7 +187,7 @@ func (pubKey PubKey) String() string { } // VRFVerify is not supported in Secp256k1. -func (pubKey PubKey) VRFVerify(proof []byte, seed []byte) (crypto.Output, error) { +func (pubKey PubKey) VRFVerify(proof []byte, message []byte) (crypto.Output, error) { return nil, fmt.Errorf("VRF verify is not supported by the secp256k1") } diff --git a/crypto/sr25519/pubkey.go b/crypto/sr25519/pubkey.go index 3f3e2a118..02b87b257 100644 --- a/crypto/sr25519/pubkey.go +++ b/crypto/sr25519/pubkey.go @@ -59,7 +59,7 @@ func (pubKey PubKey) VerifySignature(msg []byte, sig []byte) bool { } // VRFVerify is not supported in Sr25519. -func (pubKey PubKey) VRFVerify(proof []byte, seed []byte) (crypto.Output, error) { +func (pubKey PubKey) VRFVerify(proof []byte, message []byte) (crypto.Output, error) { return nil, fmt.Errorf("VRF verify is not supported by the sr25519") } diff --git a/privval/signer_client_test.go b/privval/signer_client_test.go index c2057ba99..6156c21ce 100644 --- a/privval/signer_client_test.go +++ b/privval/signer_client_test.go @@ -2,6 +2,7 @@ package privval import ( "fmt" + curve25519voi "github.com/oasisprotocol/curve25519-voi/primitives/ed25519" "testing" "time" @@ -162,16 +163,16 @@ func TestSignerGenerateVRFProof(t *testing.T) { proof, err := tc.signerClient.GenerateVRFProof(message) require.Nil(t, err) require.True(t, len(proof) > 0) - output, err := vrf.ProofToHash(vrf.Proof(proof)) + output, err := vrf.ProofToHash(proof) require.Nil(t, err) require.NotNil(t, output) pubKey, err := tc.signerClient.GetPubKey() require.Nil(t, err) ed25519PubKey, ok := pubKey.(ed25519.PubKey) require.True(t, ok) - expected, err := vrf.Verify(ed25519PubKey, vrf.Proof(proof), message) - require.Nil(t, err) - assert.True(t, expected) + flag, bz := vrf.Verify(curve25519voi.PublicKey(ed25519PubKey), proof, message) + require.NotNil(t, bz) + assert.True(t, flag) } } diff --git a/test/e2e/Makefile b/test/e2e/Makefile index 900028d5a..b1f6f8387 100644 --- a/test/e2e/Makefile +++ b/test/e2e/Makefile @@ -12,12 +12,12 @@ docker: # order to build a binary with an Ostracon node in it (for built-in # ABCI testing). node: - go build -o build/node -tags libsodium,badgerdb,boltdb,cleveldb,rocksdb ./node + go build -o build/node -tags badgerdb,boltdb,cleveldb,rocksdb ./node generator: - go build -o build/generator -tags libsodium ./generator + go build -o build/generator ./generator runner: - go build -o build/runner -tags libsodium ./runner + go build -o build/runner ./runner .PHONY: all node docker generator maverick runner diff --git a/test/e2e/docker/Dockerfile b/test/e2e/docker/Dockerfile index a1218fe42..278e10be3 100644 --- a/test/e2e/docker/Dockerfile +++ b/test/e2e/docker/Dockerfile @@ -6,8 +6,6 @@ FROM golang:1.18 RUN apt-get -qq update -y && apt-get -qq upgrade -y >/dev/null RUN apt-get -qq install -y libleveldb-dev make libc-dev libtool >/dev/null -ARG SRCDIR=/src/ostracon - # RocksDB 6.24.2+ is required to build with tm-db 0.6.7 (but RocksDB 7.x is not yet supported). # librocksdb-dev installed by apt with golang:1.18 is still 6.11, so we have to build it from the latest 6.x sources. ARG ROCKSDB_VERSION=6.29.5 @@ -19,31 +17,20 @@ RUN cd ${ROCKSDB_DIR} && make -j2 shared_lib && make install-shared RUN cp /usr/local/lib/librocksdb.so* /usr/lib RUN rm -rf ${ROCKSDB_FILE} ${ROCKSDB_DIR} -# Build/Install libsodium separately (for layer caching) -ARG VRF_ROOT=crypto/vrf/internal/vrf -ARG LIBSODIUM_ROOT=${VRF_ROOT}/libsodium -ARG LIBSODIUM_OS=${SRCDIR}/${VRF_ROOT}/sodium/linux_amd64 -COPY ${LIBSODIUM_ROOT} ${LIBSODIUM_ROOT} -RUN cd ${LIBSODIUM_ROOT} && \ - ./autogen.sh && \ - ./configure --disable-shared --prefix="${LIBSODIUM_OS}" && \ - make && \ - make install -RUN rm -rf ${LIBSODIUM_ROOT} - ENV OSTRACON_BUILD_OPTIONS badgerdb,boltdb,cleveldb,rocksdb ENV CGO_LDFLAGS -lrocksdb -ENV LIBSODIUM 1 +WORKDIR /src/ostracon # Fetch dependencies separately (for layer caching) -COPY go.mod go.sum ${SRCDIR} -RUN cd ${SRCDIR} && go mod download +COPY go.mod go.sum ./ +RUN go mod download # Build Ostracon and install into /usr/bin/ostracon -COPY . ${SRCDIR} +COPY . . +RUN make build && cp build/ostracon /usr/bin/ostracon COPY test/e2e/docker/entrypoint* /usr/bin/ -RUN cd ${SRCDIR} && make build && cp build/ostracon /usr/bin/ostracon -RUN cd ${SRCDIR}/test/e2e && make node && cp build/node /usr/bin/app + +RUN cd test/e2e && make node && cp build/node /usr/bin/app # Set up runtime directory. We don't use a separate runtime image since we need # e.g. leveldb and rocksdb which are already installed in the build image. diff --git a/test/e2e/runner/test.go b/test/e2e/runner/test.go index 77d0efe43..865c301b6 100644 --- a/test/e2e/runner/test.go +++ b/test/e2e/runner/test.go @@ -15,5 +15,5 @@ func Test(testnet *e2e.Testnet) error { return err } - return execVerbose("go", "test", "-count", "1", "-tags", "libsodium", "./tests/...") + return execVerbose("go", "test", "-count", "1", "./tests/...") } diff --git a/test/kms/bench_test.go b/test/kms/bench_test.go index fd93ee74d..ce62229cc 100644 --- a/test/kms/bench_test.go +++ b/test/kms/bench_test.go @@ -2,7 +2,6 @@ // To test, address the KMS connection to port 45666 on the machine running this program and run the following: // // $ cd test/kms -// $ go test -tags libsodium -bench . -benchmem package main import ( diff --git a/types/block_test.go b/types/block_test.go index 0c7fe7ed7..ea7c58824 100644 --- a/types/block_test.go +++ b/types/block_test.go @@ -444,7 +444,7 @@ func TestHeaderHash(t *testing.T) { s.Type().Field(i).Name) switch f := f.Interface().(type) { - case int32, int64, bytes.HexBytes, vrf.Proof, string: + case int32, int64, bytes.HexBytes, []byte, string: byteSlices = append(byteSlices, cdcEncode(f)) case time.Time: bz, err := gogotypes.StdTimeMarshal(f) @@ -1072,7 +1072,7 @@ func TestEntropyHash(t *testing.T) { s.Type().Field(i).Name) switch f := f.Interface().(type) { - case int32, int64, bytes.HexBytes, vrf.Proof, string: + case int32, int64, bytes.HexBytes, []byte, string: byteSlices = append(byteSlices, cdcEncode(f)) case time.Time: bz, err := gogotypes.StdTimeMarshal(f)