• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* Copyright (c) 2023, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15package kyber
16
17import (
18	"bufio"
19	"bytes"
20	"encoding/hex"
21	"golang.org/x/crypto/sha3"
22	"os"
23	"strings"
24	"testing"
25)
26
27func TestVectors(t *testing.T) {
28	in, err := os.Open("../../../../crypto/kyber/kyber_tests.txt")
29	if err != nil {
30		t.Error(err)
31		return
32	}
33	defer in.Close()
34
35	scanner := bufio.NewScanner(in)
36	var priv *PrivateKey
37	var encodedPublicKey *[PublicKeySize]byte
38	var ciphertext *[CiphertextSize]byte
39	sharedSecret := make([]byte, 32)
40
41	lineNo := 0
42	for scanner.Scan() {
43		lineNo++
44		line := scanner.Text()
45
46		parts := strings.Split(line, "=")
47		if len(parts) != 2 || strings.HasPrefix(line, "count ") {
48			continue
49		}
50		key := strings.TrimSpace(parts[0])
51		value, err := hex.DecodeString(strings.TrimSpace(parts[1]))
52		if err != nil {
53			t.Errorf("bad hex value on line %d: %q", lineNo, parts[1])
54			return
55		}
56
57		switch key {
58		case "generateEntropy":
59			priv, encodedPublicKey = NewPrivateKey((*[64]byte)(value))
60		case "encapEntropyPreHash":
61			hashedEntropy := sha3.Sum256(value)
62			ciphertext = priv.Encap(sharedSecret, &hashedEntropy)
63			decapSharedSecret := make([]byte, len(sharedSecret))
64			priv.Decap(decapSharedSecret, ciphertext)
65			if !bytes.Equal(sharedSecret, decapSharedSecret) {
66				t.Errorf("instance on line %d did not round trip", lineNo)
67				return
68			}
69		case "pk":
70			if !bytes.Equal(encodedPublicKey[:], value) {
71				t.Errorf("bad 'pk' value on line %d:\nwant: %x\ncalc: %x", lineNo, value, encodedPublicKey)
72				return
73			}
74		case "sk":
75			encodedPrivateKey := priv.Marshal()
76			if !bytes.Equal(encodedPrivateKey[:], value) {
77				t.Errorf("bad 'sk' value on line %d:\nwant: %x\ncalc: %x", lineNo, value, encodedPrivateKey)
78				return
79			}
80		case "ct":
81			if !bytes.Equal(ciphertext[:], value) {
82				t.Errorf("bad 'ct' value on line %d:\nwant: %x\ncalc: %x", lineNo, value, ciphertext[:])
83				return
84			}
85		case "ss":
86			if !bytes.Equal(sharedSecret[:], value) {
87				t.Errorf("bad 'ss' value on line %d:\nwant: %x\ncalc: %x", lineNo, value, sharedSecret[:])
88				return
89			}
90		}
91	}
92}
93
94func TestIteration(t *testing.T) {
95	h := sha3.NewShake256()
96
97	for i := 0; i < 4096; i++ {
98		var generateEntropy [64]byte
99		h.Read(generateEntropy[:])
100		var encapEntropy [32]byte
101		h.Read(encapEntropy[:])
102
103		priv, encodedPublicKey := NewPrivateKey(&generateEntropy)
104		h.Reset()
105		h.Write(encodedPublicKey[:])
106		encodedPrivateKey := priv.Marshal()
107		h.Write(encodedPrivateKey[:])
108
109		var sharedSecret [32]byte
110		ciphertext := priv.Encap(sharedSecret[:], &encapEntropy)
111		h.Write(ciphertext[:])
112		h.Write(sharedSecret[:])
113
114		var decapSharedSecret [32]byte
115		priv.Decap(decapSharedSecret[:], ciphertext)
116		if !bytes.Equal(decapSharedSecret[:], sharedSecret[:]) {
117			t.Errorf("Decap failed on iteration %d", i)
118			return
119		}
120	}
121
122	var result [16]byte
123	h.Read(result[:])
124	const expected = "18c6cd04eaebb33b20bb1e8e2762d30d"
125	if hex.EncodeToString(result[:]) != expected {
126		t.Errorf("iteration test produced %x, but should be %v", result, expected)
127	}
128}
129