1
2
3
4
5 package salsa20
6
7 import (
8 "bytes"
9 "encoding/hex"
10 "testing"
11 )
12
13 func fromHex(s string) []byte {
14 ret, err := hex.DecodeString(s)
15 if err != nil {
16 panic(err)
17 }
18 return ret
19 }
20
21
22
23 var testVectors = []struct {
24 key []byte
25 iv []byte
26 numBytes int
27 xor []byte
28 }{
29 {
30 fromHex("0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D"),
31 fromHex("0D74DB42A91077DE"),
32 131072,
33 fromHex("C349B6A51A3EC9B712EAED3F90D8BCEE69B7628645F251A996F55260C62EF31FD6C6B0AEA94E136C9D984AD2DF3578F78E457527B03A0450580DD874F63B1AB9"),
34 },
35 {
36 fromHex("0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12"),
37 fromHex("167DE44BB21980E7"),
38 131072,
39 fromHex("C3EAAF32836BACE32D04E1124231EF47E101367D6305413A0EEB07C60698A2876E4D031870A739D6FFDDD208597AFF0A47AC17EDB0167DD67EBA84F1883D4DFD"),
40 },
41 {
42 fromHex("0A5DB00356A9FC4FA2F5489BEE4194E73A8DE03386D92C7FD22578CB1E71C417"),
43 fromHex("1F86ED54BB2289F0"),
44 131072,
45 fromHex("3CD23C3DC90201ACC0CF49B440B6C417F0DC8D8410A716D5314C059E14B1A8D9A9FB8EA3D9C8DAE12B21402F674AA95C67B1FC514E994C9D3F3A6E41DFF5BBA6"),
46 },
47 {
48 fromHex("0F62B5085BAE0154A7FA4DA0F34699EC3F92E5388BDE3184D72A7DD02376C91C"),
49 fromHex("288FF65DC42B92F9"),
50 131072,
51 fromHex("E00EBCCD70D69152725F9987982178A2E2E139C7BCBE04CA8A0E99E318D9AB76F988C8549F75ADD790BA4F81C176DA653C1A043F11A958E169B6D2319F4EEC1A"),
52 },
53 }
54
55 func TestSalsa20(t *testing.T) {
56 var inBuf, outBuf []byte
57 var key [32]byte
58
59 for i, test := range testVectors {
60 if test.numBytes%64 != 0 {
61 t.Errorf("#%d: numBytes is not a multiple of 64", i)
62 continue
63 }
64
65 if test.numBytes > len(inBuf) {
66 inBuf = make([]byte, test.numBytes)
67 outBuf = make([]byte, test.numBytes)
68 }
69 in := inBuf[:test.numBytes]
70 out := outBuf[:test.numBytes]
71 copy(key[:], test.key)
72 XORKeyStream(out, in, test.iv, &key)
73
74 var xor [64]byte
75 for len(out) > 0 {
76 for i := 0; i < 64; i++ {
77 xor[i] ^= out[i]
78 }
79 out = out[64:]
80 }
81
82 if !bytes.Equal(xor[:], test.xor) {
83 t.Errorf("#%d: bad result", i)
84 }
85 }
86 }
87
88 var xSalsa20TestData = []struct {
89 in, nonce, key, out []byte
90 }{
91 {
92 []byte("Hello world!"),
93 []byte("24-byte nonce for xsalsa"),
94 []byte("this is 32-byte key for xsalsa20"),
95 []byte{0x00, 0x2d, 0x45, 0x13, 0x84, 0x3f, 0xc2, 0x40, 0xc4, 0x01, 0xe5, 0x41},
96 },
97 {
98 make([]byte, 64),
99 []byte("24-byte nonce for xsalsa"),
100 []byte("this is 32-byte key for xsalsa20"),
101 []byte{0x48, 0x48, 0x29, 0x7f, 0xeb, 0x1f, 0xb5, 0x2f, 0xb6,
102 0x6d, 0x81, 0x60, 0x9b, 0xd5, 0x47, 0xfa, 0xbc, 0xbe, 0x70,
103 0x26, 0xed, 0xc8, 0xb5, 0xe5, 0xe4, 0x49, 0xd0, 0x88, 0xbf,
104 0xa6, 0x9c, 0x08, 0x8f, 0x5d, 0x8d, 0xa1, 0xd7, 0x91, 0x26,
105 0x7c, 0x2c, 0x19, 0x5a, 0x7f, 0x8c, 0xae, 0x9c, 0x4b, 0x40,
106 0x50, 0xd0, 0x8c, 0xe6, 0xd3, 0xa1, 0x51, 0xec, 0x26, 0x5f,
107 0x3a, 0x58, 0xe4, 0x76, 0x48},
108 },
109 }
110
111 func TestXSalsa20(t *testing.T) {
112 var key [32]byte
113
114 for i, test := range xSalsa20TestData {
115 out := make([]byte, len(test.in))
116 copy(key[:], test.key)
117 XORKeyStream(out, test.in, test.nonce, &key)
118 if !bytes.Equal(out, test.out) {
119 t.Errorf("%d: expected %x, got %x", i, test.out, out)
120 }
121 }
122 }
123
124 var (
125 keyArray [32]byte
126 key = &keyArray
127 nonce [8]byte
128 msg = make([]byte, 1<<10)
129 )
130
131 func BenchmarkXOR1K(b *testing.B) {
132 b.StopTimer()
133 out := make([]byte, 1024)
134 b.StartTimer()
135 for i := 0; i < b.N; i++ {
136 XORKeyStream(out, msg[:1024], nonce[:], key)
137 }
138 b.SetBytes(1024)
139 }
140
View as plain text