xref: /aosp_15_r20/external/tink/go/testutil/wycheproofutil.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2019 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15////////////////////////////////////////////////////////////////////////////////
16
17package testutil
18
19import (
20	"encoding/hex"
21	"encoding/json"
22	"errors"
23	"os"
24	"path/filepath"
25	"testing"
26)
27
28const (
29	wycheproofDir = "wycheproof/testvectors"
30)
31
32// SkipTestIfTestSrcDirIsNotSet skips the test if TEST_SRCDIR is not set.
33// This is necessary when not using Blaze/Bazel, as we don't have a solution for referencing non-Go
34// resources that are external to the repository with Go tooling.
35func SkipTestIfTestSrcDirIsNotSet(t *testing.T) {
36	t.Helper()
37	if _, ok := os.LookupEnv("TEST_SRCDIR"); !ok {
38		t.Skip("TEST_SRCDIR not found")
39	}
40}
41
42// WycheproofSuite represents the common elements of the top level
43// object in a Wycheproof json file. Implementations should embed
44// WycheproofSuite in a struct that strongly types the testGroups
45// field. See wycheproofutil_test.go for an example.
46type WycheproofSuite struct {
47	Algorithm        string            `json:"algorithm"`
48	GeneratorVersion string            `json:"generatorVersion"`
49	NumberOfTests    int               `json:"numberOfTests"`
50	Notes            map[string]string `json:"notes"`
51}
52
53// WycheproofGroup represents the common elements of a testGroups
54// object in a Wycheproof suite. Implementations should embed
55// WycheproofGroup in a struct that strongly types its list of cases.
56// See wycheproofutil_test.go for an example.
57type WycheproofGroup struct {
58	Type string `json:"type"`
59}
60
61// WycheproofCase represents the common elements of a tests object
62// in a Wycheproof group. Implementation should embed WycheproofCase
63// in a struct that contains fields specific to the test type.
64// See wycheproofutil_test.go for an example.
65type WycheproofCase struct {
66	CaseID  int      `json:"tcId"`
67	Comment string   `json:"comment"`
68	Result  string   `json:"result"`
69	Flags   []string `json:"flags"`
70}
71
72// HexBytes is a helper type for unmarshalling a byte sequence represented as a
73// hex encoded string.
74type HexBytes []byte
75
76// UnmarshalText converts a hex encoded string into a sequence of bytes.
77func (a *HexBytes) UnmarshalText(text []byte) error {
78	decoded, err := hex.DecodeString(string(text))
79	if err != nil {
80		return err
81	}
82
83	*a = decoded
84	return nil
85}
86
87// PopulateSuite opens filename from the Wycheproof test vectors directory and
88// populates suite with the decoded JSON data.
89//
90// When using this in a test function, the function should start with
91// SkipTestIfTestSrcDirIsNotSet(), to expediently skip the test.
92func PopulateSuite(suite interface{}, filename string) error {
93	srcDir, ok := os.LookupEnv("TEST_SRCDIR")
94	if !ok {
95		return errors.New("TEST_SRCDIR not found")
96	}
97	f, err := os.Open(filepath.Join(srcDir, wycheproofDir, filename))
98	if err != nil {
99		return err
100	}
101	parser := json.NewDecoder(f)
102	if err := parser.Decode(suite); err != nil {
103		return err
104	}
105	return nil
106}
107