package crypt import ( "bytes" "context" "encoding/base32" "fmt" "io" "io/ioutil" "strings" "testing" "github.com/pkg/errors" "github.com/rclone/rclone/backend/crypt/pkcs7" "github.com/rclone/rclone/lib/readers" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require") func TestNewNameEncryptionMode(t *testing.T) { for _, test := range []struct { in string expected NameEncryptionMode expectedErr string }{ {"off", NameEncryptionOff, ""}, {"standard", NameEncryptionStandard, ""}, {"obfuscate", NameEncryptionObfuscated, ""}, {"potato", NameEncryptionOff, "Unknown file name encryption mode \"potato\""}, } { actual, actualErr := NewNameEncryptionMode(test.in) assert.Equal(t, actual, test.expected) if test.expectedErr == "" { assert.NoError(t, actualErr) } else { assert.Error(t, actualErr, test.expectedErr) } }} func TestNewNameEncryptionModeString(t *testing.T) { assert.Equal(t, NameEncryptionOff.String(), "off") assert.Equal(t, NameEncryptionStandard.String(), "standard") assert.Equal(t, NameEncryptionObfuscated.String(), "obfuscate") assert.Equal(t, NameEncryptionMode(3).String(), "Unknown mode #3")} func TestEncodeFileName(t *testing.T) { for _, test := range []struct { in string expected string }{ {"", ""}, {"1", "64"}, {"12", "64p0"}, {"123", "64p36"}, {"1234", "64p36d0"}, {"12345", "64p36d1l"}, {"123456", "64p36d1l6o"}, {"1234567", "64p36d1l6org"}, {"12345678", "64p36d1l6orjg"}, {"123456789", "64p36d1l6orjge8"}, {"1234567890", "64p36d1l6orjge9g"}, {"12345678901", "64p36d1l6orjge9g64"}, {"123456789012", "64p36d1l6orjge9g64p0"}, {"1234567890123", "64p36d1l6orjge9g64p36"}, {"12345678901234", "64p36d1l6orjge9g64p36d0"}, {"123456789012345", "64p36d1l6orjge9g64p36d1l"}, {"1234567890123456", "64p36d1l6orjge9g64p36d1l6o"}, } { actual := encodeFileName([]byte(test.in)) assert.Equal(t, actual, test.expected, fmt.Sprintf("in=%q", test.in)) recovered, err := decodeFileName(test.expected) assert.NoError(t, err) assert.Equal(t, string(recovered), test.in, fmt.Sprintf("reverse=%q", test.expected)) in := strings.ToUpper(test.expected) recovered, err = decodeFileName(in) assert.NoError(t, err) assert.Equal(t, string(recovered), test.in, fmt.Sprintf("reverse=%q", in)) }} func TestDecodeFileName(t *testing.T) { // We've tested decoding the valid ones above, now concentrate on the invalid ones for _, test := range []struct { in string expectedErr error }{ {"64=", ErrorBadBase32Encoding}, {"!", base32.CorruptInputError(0)}, {"hello=hello", base32.CorruptInputError(5)}, } { actual, actualErr := decodeFileName(test.in) assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr)) }} func TestEncryptSegment(t *testing.T) { c, _ := newCipher(NameEncryptionStandard, "", "", true) for _, test := range []struct { in string expected string }{ {"", ""}, {"1", "p0e52nreeaj0a5ea7s64m4j72s"}, {"12", "l42g6771hnv3an9cgc8cr2n1ng"}, {"123", "qgm4avr35m5loi1th53ato71v0"}, {"1234", "8ivr2e9plj3c3esisjpdisikos"}, {"12345", "rh9vu63q3o29eqmj4bg6gg7s44"}, {"123456", "bn717l3alepn75b2fb2ejmi4b4"}, {"1234567", "n6bo9jmb1qe3b1ogtj5qkf19k8"}, {"12345678", "u9t24j7uaq94dh5q53m3s4t9ok"}, {"123456789", "37hn305g6j12d1g0kkrl7ekbs4"}, {"1234567890", "ot8d91eplaglb62k2b1trm2qv0"}, {"12345678901", "h168vvrgb53qnrtvvmb378qrcs"}, {"123456789012", "s3hsdf9e29ithrqbjqu01t8q2s"}, {"1234567890123", "cf3jimlv1q2oc553mv7s3mh3eo"}, {"12345678901234", "moq0uqdlqrblrc5pa5u5c7hq9g"}, {"123456789012345", "eeam3li4rnommi3a762h5n7meg"}, {"1234567890123456", "mijbj0frqf6ms7frcr6bd9h0env53jv96pjaaoirk7forcgpt70g"}, } { actual := c.encryptSegment(test.in) assert.Equal(t, test.expected, actual, fmt.Sprintf("Testing %q", test.in)) recovered, err := c.decryptSegment(test.expected) assert.NoError(t, err, fmt.Sprintf("Testing reverse %q", test.expected)) assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %q", test.expected)) in := strings.ToUpper(test.expected) recovered, err = c.decryptSegment(in) assert.NoError(t, err, fmt.Sprintf("Testing reverse %q", in)) assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %q", in)) }} func TestDecryptSegment(t *testing.T) { // We've tested the forwards above, now concentrate on the errors longName := make([]byte, 3328) for i := range longName { longName[i] = 'a' } c, _ := newCipher(NameEncryptionStandard, "", "", true) for _, test := range []struct { in string expectedErr error }{ {"64=", ErrorBadBase32Encoding}, {"!", base32.CorruptInputError(0)}, {string(longName), ErrorTooLongAfterDecode}, {encodeFileName([]byte("a")), ErrorNotAMultipleOfBlocksize}, {encodeFileName([]byte("123456789abcdef")), ErrorNotAMultipleOfBlocksize}, {encodeFileName([]byte("123456789abcdef0")), pkcs7.ErrorPaddingTooLong}, } { actual, actualErr := c.decryptSegment(test.in) assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr)) }} func TestEncryptFileName(t *testing.T) { // First standard mode c, _ := newCipher(NameEncryptionStandard, "", "", true) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptFileName("1")) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptFileName("1/12")) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", c.EncryptFileName("1/12/123")) // Standard mode with directory name encryption off c, _ = newCipher(NameEncryptionStandard, "", "", false) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptFileName("1")) assert.Equal(t, "1/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptFileName("1/12")) assert.Equal(t, "1/12/qgm4avr35m5loi1th53ato71v0", c.EncryptFileName("1/12/123")) // Now off mode c, _ = newCipher(NameEncryptionOff, "", "", true) assert.Equal(t, "1/12/123.bin", c.EncryptFileName("1/12/123")) // Obfuscation mode c, _ = newCipher(NameEncryptionObfuscated, "", "", true) assert.Equal(t, "49.6/99.23/150.890/53.!!lipps", c.EncryptFileName("1/12/123/!hello")) assert.Equal(t, "161.\u00e4", c.EncryptFileName("\u00a1")) assert.Equal(t, "160.\u03c2", c.EncryptFileName("\u03a0")) // Obfuscation mode with directory name encryption off c, _ = newCipher(NameEncryptionObfuscated, "", "", false) assert.Equal(t, "1/12/123/53.!!lipps", c.EncryptFileName("1/12/123/!hello")) assert.Equal(t, "161.\u00e4", c.EncryptFileName("\u00a1")) assert.Equal(t, "160.\u03c2", c.EncryptFileName("\u03a0"))} func TestDecryptFileName(t *testing.T) { for _, test := range []struct { mode NameEncryptionMode dirNameEncrypt bool in string expected string expectedErr error }{ {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s", "1", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "1/12", nil}, {NameEncryptionStandard, true, "p0e52nreeAJ0A5EA7S64M4J72S/L42G6771HNv3an9cgc8cr2n1ng", "1/12", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1/qgm4avr35m5loi1th53ato71v0", "", ErrorNotAMultipleOfBlocksize}, {NameEncryptionStandard, false, "1/12/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil}, {NameEncryptionOff, true, "1/12/123.bin", "1/12/123", nil}, {NameEncryptionOff, true, "1/12/123.bix", "", ErrorNotAnEncryptedFile}, {NameEncryptionOff, true, ".bin", "", ErrorNotAnEncryptedFile}, {NameEncryptionObfuscated, true, "!.hello", "hello", nil}, {NameEncryptionObfuscated, true, "hello", "", ErrorNotAnEncryptedFile}, {NameEncryptionObfuscated, true, "161.\u00e4", "\u00a1", nil}, {NameEncryptionObfuscated, true, "160.\u03c2", "\u03a0", nil}, {NameEncryptionObfuscated, false, "1/12/123/53.!!lipps", "1/12/123/!hello", nil}, } { c, _ := newCipher(test.mode, "", "", test.dirNameEncrypt) actual, actualErr := c.DecryptFileName(test.in) what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode) assert.Equal(t, test.expected, actual, what) assert.Equal(t, test.expectedErr, actualErr, what) }} func TestEncDecMatches(t *testing.T) { for _, test := range []struct { mode NameEncryptionMode in string }{ {NameEncryptionStandard, "1/2/3/4"}, {NameEncryptionOff, "1/2/3/4"}, {NameEncryptionObfuscated, "1/2/3/4/!hello\u03a0"}, {NameEncryptionObfuscated, "Avatar The Last Airbender"}, } { c, _ := newCipher(test.mode, "", "", true) out, err := c.DecryptFileName(c.EncryptFileName(test.in)) what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode) assert.Equal(t, out, test.in, what) assert.Equal(t, err, nil, what) }} func TestEncryptDirName(t *testing.T) { // First standard mode c, _ := newCipher(NameEncryptionStandard, "", "", true) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptDirName("1")) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptDirName("1/12")) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", c.EncryptDirName("1/12/123")) // Standard mode with dir name encryption off c, _ = newCipher(NameEncryptionStandard, "", "", false) assert.Equal(t, "1/12", c.EncryptDirName("1/12")) assert.Equal(t, "1/12/123", c.EncryptDirName("1/12/123")) // Now off mode c, _ = newCipher(NameEncryptionOff, "", "", true) assert.Equal(t, "1/12/123", c.EncryptDirName("1/12/123"))} func TestDecryptDirName(t *testing.T) { for _, test := range []struct { mode NameEncryptionMode dirNameEncrypt bool in string expected string expectedErr error }{ {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s", "1", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "1/12", nil}, {NameEncryptionStandard, true, "p0e52nreeAJ0A5EA7S64M4J72S/L42G6771HNv3an9cgc8cr2n1ng", "1/12", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1/qgm4avr35m5loi1th53ato71v0", "", ErrorNotAMultipleOfBlocksize}, {NameEncryptionStandard, false, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", nil}, {NameEncryptionStandard, false, "1/12/123", "1/12/123", nil}, {NameEncryptionOff, true, "1/12/123.bin", "1/12/123.bin", nil}, {NameEncryptionOff, true, "1/12/123", "1/12/123", nil}, {NameEncryptionOff, true, ".bin", ".bin", nil}, } { c, _ := newCipher(test.mode, "", "", test.dirNameEncrypt) actual, actualErr := c.DecryptDirName(test.in) what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode) assert.Equal(t, test.expected, actual, what) assert.Equal(t, test.expectedErr, actualErr, what) }} func TestEncryptedSize(t *testing.T) { c, _ := newCipher(NameEncryptionStandard, "", "", true) for _, test := range []struct { in int64 expected int64 }{ {0, 32}, {1, 32 + 16 + 1}, {65536, 32 + 16 + 65536}, {65537, 32 + 16 + 65536 + 16 + 1}, {1 << 20, 32 + 16*(16+65536)}, {(1 << 20) + 65535, 32 + 16*(16+65536) + 16 + 65535}, {1 << 30, 32 + 16384*(16+65536)}, {(1 << 40) + 1, 32 + 16777216*(16+65536) + 16 + 1}, } { actual := c.EncryptedSize(test.in) assert.Equal(t, test.expected, actual, fmt.Sprintf("Testing %d", test.in)) recovered, err := c.DecryptedSize(test.expected) assert.NoError(t, err, fmt.Sprintf("Testing reverse %d", test.expected)) assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %d", test.expected)) }} func TestDecryptedSize(t *testing.T) { // Test the errors since we tested the reverse above c, _ := newCipher(NameEncryptionStandard, "", "", true) for _, test := range []struct { in int64 expectedErr error }{ {0, ErrorEncryptedFileTooShort}, {0, ErrorEncryptedFileTooShort}, {1, ErrorEncryptedFileTooShort}, {7, ErrorEncryptedFileTooShort}, {32 + 1, ErrorEncryptedFileBadHeader}, {32 + 16, ErrorEncryptedFileBadHeader}, {32 + 16 + 65536 + 1, ErrorEncryptedFileBadHeader}, {32 + 16 + 65536 + 16, ErrorEncryptedFileBadHeader}, } { _, actualErr := c.DecryptedSize(test.in) assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("Testing %d", test.in)) }} func TestNoncePointer(t *testing.T) { var x nonce assert.Equal(t, (*[24]byte)(&x), x.pointer())} func TestNonceFromReader(t *testing.T) { var x nonce buf := bytes.NewBufferString("123456789abcdefghijklmno") err := x.fromReader(buf) assert.NoError(t, err) assert.Equal(t, nonce{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, x) buf = bytes.NewBufferString("123456789abcdefghijklmn") err = x.fromReader(buf) assert.Error(t, err, "short read of nonce")} func TestNonceFromBuf(t *testing.T) { var x nonce buf := []byte("123456789abcdefghijklmnoXXXXXXXX") x.fromBuf(buf) assert.Equal(t, nonce{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, x) buf = []byte("0123456789abcdefghijklmn") x.fromBuf(buf) assert.Equal(t, nonce{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}, x) buf = []byte("0123456789abcdefghijklm") assert.Panics(t, func() { x.fromBuf(buf) })} func TestNonceIncrement(t *testing.T) { for _, test := range []struct { in nonce out nonce }{ { nonce{0x00}, nonce{0x01}, }, { nonce{0xFF}, nonce{0x00, 0x01}, }, { nonce{0xFF, 0xFF}, nonce{0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }, } { x := test.in x.increment() assert.Equal(t, test.out, x) }} func TestNonceAdd(t *testing.T) { for _, test := range []struct { add uint64 in nonce out nonce }{ { 0x01, nonce{0x00}, nonce{0x01}, }, { 0xFF, nonce{0xFF}, nonce{0xFE, 0x01}, }, { 0xFFFF, nonce{0xFF, 0xFF}, nonce{0xFE, 0xFF, 0x01}, }, { 0xFFFFFF, nonce{0xFF, 0xFF, 0xFF}, nonce{0xFE, 0xFF, 0xFF, 0x01}, }, { 0xFFFFFFFF, nonce{0xFF, 0xFF, 0xFF, 0xFF}, nonce{0xFe, 0xFF, 0xFF, 0xFF, 0x01}, }, { 0xFFFFFFFFFF, nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}, }, { 0xFFFFFFFFFFFF, nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}, }, { 0xFFFFFFFFFFFFFF,Lines 1–500 of 1224. Load more
package crypt import ( "bytes" "context" "encoding/base32" "fmt" "io" "io/ioutil" "strings" "testing" "github.com/pkg/errors" "github.com/rclone/rclone/backend/crypt/pkcs7" "github.com/rclone/rclone/lib/readers" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestNewNameEncryptionMode(t *testing.T) { for _, test := range []struct { in string expected NameEncryptionMode expectedErr string }{ {"off", NameEncryptionOff, ""}, {"standard", NameEncryptionStandard, ""}, {"obfuscate", NameEncryptionObfuscated, ""}, {"potato", NameEncryptionOff, "Unknown file name encryption mode \"potato\""}, } { actual, actualErr := NewNameEncryptionMode(test.in) assert.Equal(t, actual, test.expected) if test.expectedErr == "" { assert.NoError(t, actualErr) } else { assert.Error(t, actualErr, test.expectedErr) } } } func TestNewNameEncryptionModeString(t *testing.T) { assert.Equal(t, NameEncryptionOff.String(), "off") assert.Equal(t, NameEncryptionStandard.String(), "standard") assert.Equal(t, NameEncryptionObfuscated.String(), "obfuscate") assert.Equal(t, NameEncryptionMode(3).String(), "Unknown mode #3") } func TestEncodeFileName(t *testing.T) { for _, test := range []struct { in string expected string }{ {"", ""}, {"1", "64"}, {"12", "64p0"}, {"123", "64p36"}, {"1234", "64p36d0"}, {"12345", "64p36d1l"}, {"123456", "64p36d1l6o"}, {"1234567", "64p36d1l6org"}, {"12345678", "64p36d1l6orjg"}, {"123456789", "64p36d1l6orjge8"}, {"1234567890", "64p36d1l6orjge9g"}, {"12345678901", "64p36d1l6orjge9g64"}, {"123456789012", "64p36d1l6orjge9g64p0"}, {"1234567890123", "64p36d1l6orjge9g64p36"}, {"12345678901234", "64p36d1l6orjge9g64p36d0"}, {"123456789012345", "64p36d1l6orjge9g64p36d1l"}, {"1234567890123456", "64p36d1l6orjge9g64p36d1l6o"}, } { actual := encodeFileName([]byte(test.in)) assert.Equal(t, actual, test.expected, fmt.Sprintf("in=%q", test.in)) recovered, err := decodeFileName(test.expected) assert.NoError(t, err) assert.Equal(t, string(recovered), test.in, fmt.Sprintf("reverse=%q", test.expected)) in := strings.ToUpper(test.expected) recovered, err = decodeFileName(in) assert.NoError(t, err) assert.Equal(t, string(recovered), test.in, fmt.Sprintf("reverse=%q", in)) } } func TestDecodeFileName(t *testing.T) { // We've tested decoding the valid ones above, now concentrate on the invalid ones for _, test := range []struct { in string expectedErr error }{ {"64=", ErrorBadBase32Encoding}, {"!", base32.CorruptInputError(0)}, {"hello=hello", base32.CorruptInputError(5)}, } { actual, actualErr := decodeFileName(test.in) assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr)) } } func TestEncryptSegment(t *testing.T) { c, _ := newCipher(NameEncryptionStandard, "", "", true) for _, test := range []struct { in string expected string }{ {"", ""}, {"1", "p0e52nreeaj0a5ea7s64m4j72s"}, {"12", "l42g6771hnv3an9cgc8cr2n1ng"}, {"123", "qgm4avr35m5loi1th53ato71v0"}, {"1234", "8ivr2e9plj3c3esisjpdisikos"}, {"12345", "rh9vu63q3o29eqmj4bg6gg7s44"}, {"123456", "bn717l3alepn75b2fb2ejmi4b4"}, {"1234567", "n6bo9jmb1qe3b1ogtj5qkf19k8"}, {"12345678", "u9t24j7uaq94dh5q53m3s4t9ok"}, {"123456789", "37hn305g6j12d1g0kkrl7ekbs4"}, {"1234567890", "ot8d91eplaglb62k2b1trm2qv0"}, {"12345678901", "h168vvrgb53qnrtvvmb378qrcs"}, {"123456789012", "s3hsdf9e29ithrqbjqu01t8q2s"}, {"1234567890123", "cf3jimlv1q2oc553mv7s3mh3eo"}, {"12345678901234", "moq0uqdlqrblrc5pa5u5c7hq9g"}, {"123456789012345", "eeam3li4rnommi3a762h5n7meg"}, {"1234567890123456", "mijbj0frqf6ms7frcr6bd9h0env53jv96pjaaoirk7forcgpt70g"}, } { actual := c.encryptSegment(test.in) assert.Equal(t, test.expected, actual, fmt.Sprintf("Testing %q", test.in)) recovered, err := c.decryptSegment(test.expected) assert.NoError(t, err, fmt.Sprintf("Testing reverse %q", test.expected)) assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %q", test.expected)) in := strings.ToUpper(test.expected) recovered, err = c.decryptSegment(in) assert.NoError(t, err, fmt.Sprintf("Testing reverse %q", in)) assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %q", in)) } } func TestDecryptSegment(t *testing.T) { // We've tested the forwards above, now concentrate on the errors longName := make([]byte, 3328) for i := range longName { longName[i] = 'a' } c, _ := newCipher(NameEncryptionStandard, "", "", true) for _, test := range []struct { in string expectedErr error }{ {"64=", ErrorBadBase32Encoding}, {"!", base32.CorruptInputError(0)}, {string(longName), ErrorTooLongAfterDecode}, {encodeFileName([]byte("a")), ErrorNotAMultipleOfBlocksize}, {encodeFileName([]byte("123456789abcdef")), ErrorNotAMultipleOfBlocksize}, {encodeFileName([]byte("123456789abcdef0")), pkcs7.ErrorPaddingTooLong}, } { actual, actualErr := c.decryptSegment(test.in) assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr)) } } func TestEncryptFileName(t *testing.T) { // First standard mode c, _ := newCipher(NameEncryptionStandard, "", "", true) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptFileName("1")) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptFileName("1/12")) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", c.EncryptFileName("1/12/123")) // Standard mode with directory name encryption off c, _ = newCipher(NameEncryptionStandard, "", "", false) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptFileName("1")) assert.Equal(t, "1/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptFileName("1/12")) assert.Equal(t, "1/12/qgm4avr35m5loi1th53ato71v0", c.EncryptFileName("1/12/123")) // Now off mode c, _ = newCipher(NameEncryptionOff, "", "", true) assert.Equal(t, "1/12/123.bin", c.EncryptFileName("1/12/123")) // Obfuscation mode c, _ = newCipher(NameEncryptionObfuscated, "", "", true) assert.Equal(t, "49.6/99.23/150.890/53.!!lipps", c.EncryptFileName("1/12/123/!hello")) assert.Equal(t, "161.\u00e4", c.EncryptFileName("\u00a1")) assert.Equal(t, "160.\u03c2", c.EncryptFileName("\u03a0")) // Obfuscation mode with directory name encryption off c, _ = newCipher(NameEncryptionObfuscated, "", "", false) assert.Equal(t, "1/12/123/53.!!lipps", c.EncryptFileName("1/12/123/!hello")) assert.Equal(t, "161.\u00e4", c.EncryptFileName("\u00a1")) assert.Equal(t, "160.\u03c2", c.EncryptFileName("\u03a0")) } func TestDecryptFileName(t *testing.T) { for _, test := range []struct { mode NameEncryptionMode dirNameEncrypt bool in string expected string expectedErr error }{ {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s", "1", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "1/12", nil}, {NameEncryptionStandard, true, "p0e52nreeAJ0A5EA7S64M4J72S/L42G6771HNv3an9cgc8cr2n1ng", "1/12", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1/qgm4avr35m5loi1th53ato71v0", "", ErrorNotAMultipleOfBlocksize}, {NameEncryptionStandard, false, "1/12/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil}, {NameEncryptionOff, true, "1/12/123.bin", "1/12/123", nil}, {NameEncryptionOff, true, "1/12/123.bix", "", ErrorNotAnEncryptedFile}, {NameEncryptionOff, true, ".bin", "", ErrorNotAnEncryptedFile}, {NameEncryptionObfuscated, true, "!.hello", "hello", nil}, {NameEncryptionObfuscated, true, "hello", "", ErrorNotAnEncryptedFile}, {NameEncryptionObfuscated, true, "161.\u00e4", "\u00a1", nil}, {NameEncryptionObfuscated, true, "160.\u03c2", "\u03a0", nil}, {NameEncryptionObfuscated, false, "1/12/123/53.!!lipps", "1/12/123/!hello", nil}, } { c, _ := newCipher(test.mode, "", "", test.dirNameEncrypt) actual, actualErr := c.DecryptFileName(test.in) what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode) assert.Equal(t, test.expected, actual, what) assert.Equal(t, test.expectedErr, actualErr, what) } } func TestEncDecMatches(t *testing.T) { for _, test := range []struct { mode NameEncryptionMode in string }{ {NameEncryptionStandard, "1/2/3/4"}, {NameEncryptionOff, "1/2/3/4"}, {NameEncryptionObfuscated, "1/2/3/4/!hello\u03a0"}, {NameEncryptionObfuscated, "Avatar The Last Airbender"}, } { c, _ := newCipher(test.mode, "", "", true) out, err := c.DecryptFileName(c.EncryptFileName(test.in)) what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode) assert.Equal(t, out, test.in, what) assert.Equal(t, err, nil, what) } } func TestEncryptDirName(t *testing.T) { // First standard mode c, _ := newCipher(NameEncryptionStandard, "", "", true) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptDirName("1")) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptDirName("1/12")) assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", c.EncryptDirName("1/12/123")) // Standard mode with dir name encryption off c, _ = newCipher(NameEncryptionStandard, "", "", false) assert.Equal(t, "1/12", c.EncryptDirName("1/12")) assert.Equal(t, "1/12/123", c.EncryptDirName("1/12/123")) // Now off mode c, _ = newCipher(NameEncryptionOff, "", "", true) assert.Equal(t, "1/12/123", c.EncryptDirName("1/12/123")) } func TestDecryptDirName(t *testing.T) { for _, test := range []struct { mode NameEncryptionMode dirNameEncrypt bool in string expected string expectedErr error }{ {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s", "1", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "1/12", nil}, {NameEncryptionStandard, true, "p0e52nreeAJ0A5EA7S64M4J72S/L42G6771HNv3an9cgc8cr2n1ng", "1/12", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil}, {NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1/qgm4avr35m5loi1th53ato71v0", "", ErrorNotAMultipleOfBlocksize}, {NameEncryptionStandard, false, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", nil}, {NameEncryptionStandard, false, "1/12/123", "1/12/123", nil}, {NameEncryptionOff, true, "1/12/123.bin", "1/12/123.bin", nil}, {NameEncryptionOff, true, "1/12/123", "1/12/123", nil}, {NameEncryptionOff, true, ".bin", ".bin", nil}, } { c, _ := newCipher(test.mode, "", "", test.dirNameEncrypt) actual, actualErr := c.DecryptDirName(test.in) what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode) assert.Equal(t, test.expected, actual, what) assert.Equal(t, test.expectedErr, actualErr, what) } } func TestEncryptedSize(t *testing.T) { c, _ := newCipher(NameEncryptionStandard, "", "", true) for _, test := range []struct { in int64 expected int64 }{ {0, 32}, {1, 32 + 16 + 1}, {65536, 32 + 16 + 65536}, {65537, 32 + 16 + 65536 + 16 + 1}, {1 << 20, 32 + 16*(16+65536)}, {(1 << 20) + 65535, 32 + 16*(16+65536) + 16 + 65535}, {1 << 30, 32 + 16384*(16+65536)}, {(1 << 40) + 1, 32 + 16777216*(16+65536) + 16 + 1}, } { actual := c.EncryptedSize(test.in) assert.Equal(t, test.expected, actual, fmt.Sprintf("Testing %d", test.in)) recovered, err := c.DecryptedSize(test.expected) assert.NoError(t, err, fmt.Sprintf("Testing reverse %d", test.expected)) assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %d", test.expected)) } } func TestDecryptedSize(t *testing.T) { // Test the errors since we tested the reverse above c, _ := newCipher(NameEncryptionStandard, "", "", true) for _, test := range []struct { in int64 expectedErr error }{ {0, ErrorEncryptedFileTooShort}, {0, ErrorEncryptedFileTooShort}, {1, ErrorEncryptedFileTooShort}, {7, ErrorEncryptedFileTooShort}, {32 + 1, ErrorEncryptedFileBadHeader}, {32 + 16, ErrorEncryptedFileBadHeader}, {32 + 16 + 65536 + 1, ErrorEncryptedFileBadHeader}, {32 + 16 + 65536 + 16, ErrorEncryptedFileBadHeader}, } { _, actualErr := c.DecryptedSize(test.in) assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("Testing %d", test.in)) } } func TestNoncePointer(t *testing.T) { var x nonce assert.Equal(t, (*[24]byte)(&x), x.pointer()) } func TestNonceFromReader(t *testing.T) { var x nonce buf := bytes.NewBufferString("123456789abcdefghijklmno") err := x.fromReader(buf) assert.NoError(t, err) assert.Equal(t, nonce{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, x) buf = bytes.NewBufferString("123456789abcdefghijklmn") err = x.fromReader(buf) assert.Error(t, err, "short read of nonce") } func TestNonceFromBuf(t *testing.T) { var x nonce buf := []byte("123456789abcdefghijklmnoXXXXXXXX") x.fromBuf(buf) assert.Equal(t, nonce{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, x) buf = []byte("0123456789abcdefghijklmn") x.fromBuf(buf) assert.Equal(t, nonce{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}, x) buf = []byte("0123456789abcdefghijklm") assert.Panics(t, func() { x.fromBuf(buf) }) } func TestNonceIncrement(t *testing.T) { for _, test := range []struct { in nonce out nonce }{ { nonce{0x00}, nonce{0x01}, }, { nonce{0xFF}, nonce{0x00, 0x01}, }, { nonce{0xFF, 0xFF}, nonce{0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, }, { nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }, } { x := test.in x.increment() assert.Equal(t, test.out, x) } } func TestNonceAdd(t *testing.T) { for _, test := range []struct { add uint64 in nonce out nonce }{ { 0x01, nonce{0x00}, nonce{0x01}, }, { 0xFF, nonce{0xFF}, nonce{0xFE, 0x01}, }, { 0xFFFF, nonce{0xFF, 0xFF}, nonce{0xFE, 0xFF, 0x01}, }, { 0xFFFFFF, nonce{0xFF, 0xFF, 0xFF}, nonce{0xFE, 0xFF, 0xFF, 0x01}, }, { 0xFFFFFFFF, nonce{0xFF, 0xFF, 0xFF, 0xFF}, nonce{0xFe, 0xFF, 0xFF, 0xFF, 0x01}, }, { 0xFFFFFFFFFF, nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}, }, { 0xFFFFFFFFFFFF, nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}, }, { 0xFFFFFFFFFFFFFF,