-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaesitb_parity_test.go
More file actions
121 lines (111 loc) · 4.06 KB
/
Copy pathaesitb_parity_test.go
File metadata and controls
121 lines (111 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package itb_test
import (
"encoding/hex"
"testing"
"github.com/everanium/itb/aesitb"
"github.com/everanium/itb/hashes"
)
// Production-vs-reference parity for AES-ITB-128. Every vector below was
// generated by the Python reference and is duplicated verbatim in
// aesitb/aesitb_test.go; production (itb root) and the leaf reference
// (aesitb) are checked against each other and against the recorded hex.
//
// Inputs: key = 00 11 22 .. FF; generic data = 0x00, 0x01, ... (dataLen
// bytes).
type aesitbGenericVector struct {
dataLen int
seed0, seed1 uint64
want string
}
var aesitbParityKey = [16]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
func aesitbParityData(n int) []byte {
out := make([]byte, n)
for i := range out {
out[i] = byte(i)
}
return out
}
var aesitbGenericVectors = []aesitbGenericVector{
{0, 0x0, 0x0, "d03e268799c14203bdb3e663165d6b23"},
{1, 0x0, 0x0, "f2a4e404c80c84451e35cadcc7f22bb9"},
{15, 0x0, 0x0, "95be57f5a239f3ab144382b7cd8695de"},
{16, 0x0, 0x0, "3171e8f8165c8ff5203ac9aa371c719a"},
{17, 0x0, 0x0, "48d3f6fcc2985cf31a074ea2c78b1d09"},
{31, 0x0, 0x0, "064e72d014e7a41c4fc3b7d1b938f625"},
{32, 0x0, 0x0, "e08f48e9037d3bc81d03dc0adc1b9d3b"},
{33, 0x0, 0x0, "7370df93d8fd5e118d33484f582e1750"},
{63, 0x0, 0x0, "c17822cc92d1a5fb712a1ea655de82ad"},
{64, 0x0, 0x0, "81615890aab0306bf4b32bbe2d7ca1af"},
{0, 0x1, 0x0, "787e6d0bae570d2ec58796bcbf68c172"},
{0, 0x0, 0x1, "e9d430852929ab3d88c240ddc40f823c"},
{5, 0x123456789abcdef, 0xfedcba9876543210, "7486079419f3f0767b579065d6cc3d93"},
{16, 0xffffffffffffffff, 0xffffffffffffffff, "2eae20695db216506bd63f96fda12ca0"},
{33, 0x7, 0x9, "dccfc56b263e1a2fc13052534f15092e"},
{64, 0x8000000000000000, 0x1, "a7a8e09b329611b7aec6a97b0e75cd25"},
}
// aesitbWords16 lays a HashFunc128 (lo, hi) pair out as the 16-byte
// little-endian block the reference API returns.
func aesitbWords16(lo, hi uint64) [16]byte {
var out [16]byte
for i := 0; i < 8; i++ {
out[i] = byte(lo >> (8 * i))
out[8+i] = byte(hi >> (8 * i))
}
return out
}
func TestAESITBParityGeneric(t *testing.T) {
single, _, key, err := hashes.Make128Pair(hashes.CipherAESITB128, aesitbParityKey[:])
if err != nil {
t.Fatalf("Make128Pair: %v", err)
}
if string(key) != string(aesitbParityKey[:]) {
t.Fatalf("Make128Pair returned key %x, want %x", key, aesitbParityKey)
}
for _, v := range aesitbGenericVectors {
data := aesitbParityData(v.dataLen)
lo, hi := single(data, v.seed0, v.seed1)
p := aesitbWords16(lo, hi)
r := aesitb.HashGeneric(aesitbParityKey, data, v.seed0, v.seed1)
if p != r {
t.Errorf("len=%d seeds=(%#x,%#x): production %x != reference %x", v.dataLen, v.seed0, v.seed1, p, r)
}
if got := hex.EncodeToString(p[:]); got != v.want {
t.Errorf("len=%d seeds=(%#x,%#x): got %s want %s", v.dataLen, v.seed0, v.seed1, got, v.want)
}
}
}
func TestAESITBParityBatch(t *testing.T) {
single, batched, _, err := hashes.Make128Pair(hashes.CipherAESITB128, aesitbParityKey[:])
if err != nil {
t.Fatalf("Make128Pair: %v", err)
}
if batched == nil {
t.Fatal("Make128Pair returned a nil batched arm for aesitb128")
}
// Four lanes with distinct lengths (empty, tail-only, full block,
// multi-block) and distinct seeds, all drawn from the generic vectors.
picks := []int{0, 12, 13, 15}
var lanes [4][]byte
var seeds [4][2]uint64
for i, p := range picks {
v := aesitbGenericVectors[p]
lanes[i] = aesitbParityData(v.dataLen)
seeds[i] = [2]uint64{v.seed0, v.seed1}
}
out := batched(&lanes, seeds)
for i, p := range picks {
v := aesitbGenericVectors[p]
lo, hi := single(lanes[i], seeds[i][0], seeds[i][1])
if out[i][0] != lo || out[i][1] != hi {
t.Errorf("lane %d: batched (%#x,%#x) != single (%#x,%#x)", i, out[i][0], out[i][1], lo, hi)
}
b := aesitbWords16(out[i][0], out[i][1])
r := aesitb.HashGeneric(aesitbParityKey, lanes[i], seeds[i][0], seeds[i][1])
if b != r {
t.Errorf("lane %d: batched %x != reference %x", i, b, r)
}
if got := hex.EncodeToString(b[:]); got != v.want {
t.Errorf("lane %d: got %s want %s", i, got, v.want)
}
}
}