pax_global_header00006660000000000000000000000064152070605630014516gustar00rootroot0000000000000052 comment=e982ca4d93b0d1fe615347ab37e61a11b0879a20 golang-github-enceve-crypto-0.0~git20160707.34d48bb/000077500000000000000000000000001520706056300214675ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/.travis.yml000066400000000000000000000000321520706056300235730ustar00rootroot00000000000000language: go go: - 1.6 golang-github-enceve-crypto-0.0~git20160707.34d48bb/LICENSE000066400000000000000000000167431520706056300225070ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. golang-github-enceve-crypto-0.0~git20160707.34d48bb/README.md000066400000000000000000000054641520706056300227570ustar00rootroot00000000000000[![Build Status](https://api.travis-ci.org/enceve/crypto.svg?branch=master)](https://api.travis-ci.org/enceve/crypto) [![Godoc Reference](https://godoc.org/github.com/enceve/crypto?status.svg)](https://godoc.org/github.com/enceve/crypto) [![Go Report](https://goreportcard.com/badge/github.com/enceve/crypto)](https://goreportcard.com/report/github.com/enceve/crypto) ## The *crypto* package **Notice**: The public API is not stable and backward compatibility is currently not guaranteed. This code should currently NOT used in productive environments! ### Introduction The `crypto` package implements some additional cryptographic functionality, currently not supported by the standard or additional [golang packages](https://golang.org/pkg/ "offical golang packages"). This repository should not replace or somehow compete with the [golang crypto packages](https://godoc.org/golang.org/x/crypto "Additional golang crypto packages"). Rather, this package should supplement the official and additional golang cryptographic. **Currently implemented**: - The [BLAKE2b and BLAKE2s](https://blake2.net/ "offical BLAKE2 site") hash functions. - The [Camellia](https://tools.ietf.org/html/rfc3713 "RFC 3713") block cipher. - The [ChaCha20](https://tools.ietf.org/html/rfc7539 "RFC 7539") stream cipher. - The [CMac](https://tools.ietf.org/html/rfc4493 "RFC 4493") message authentication code (OMAC1). - The [HC-128 and HC-256](https://en.wikipedia.org/wiki/HC-256 "Wikipedia") stream ciphers - The [Poly1305](https://tools.ietf.org/html/rfc7539 "RFC 7539") message authentication code. - The [Serpent](https://www.cl.cam.ac.uk/~rja14/serpent.html "offical Serpent site") block cipher. - The [SipHash](https://131002.net/siphash/ "offical SipHash site") message authentication code. - The [Skein](http://skein-hash.info/ "offical Skein site") hash function. - The [Threefish](http://skein-hash.info/ "offical Skein/Threefish site") tweakable block cipher. - The [Diffie-Hellman](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange "Wikipedia") and [ECDH](https://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman "Wikipedia") key exchange. - The [EAX](https://en.wikipedia.org/wiki/EAX_mode "Wikipedia") AEAD block cipher mode. - Some [Padding](https://en.wikipedia.org/wiki/Padding_%28cryptography%29 "Wikipedia") schemes for block ciphers. ### Aim The aim of this project / repository is a powerful, flexible and easy to use cryptographic library, which can be easily integrated into Go applications. ### Installation Install in your GOPATH: `go get -u github.com/enceve/crypto` Install Dependencies: `go get -u golang.org/x/crypto` ### Contribute First of all: **Contributions are welcome!** If you have an idea or found a bug - please raise an issue. If you want to add functionality - as usual on github send a pull request. golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/000077500000000000000000000000001520706056300226275ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2.go000066400000000000000000000113671520706056300243260ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package blake2 implements the both hash functions BLAKE2b and // BLAKE2s described in RFC 7693. // RFC 7693 only specifies BLAKE2 as pure hash and mac function, // but BLAKE2 supports also salted (randomized) and personalized // hashing. These features are implemented in the blake2b package // for BLAKE2b and in the blake2s package for BLAKE2s. package blake2 import ( "github.com/enceve/crypto/blake2/blake2b" "github.com/enceve/crypto/blake2/blake2s" ) var ( hVal512 = [8]uint64{ 0x6a09e667f2bdc948, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, } hVal256b = [8]uint64{ 0x6a09e667f2bdc928, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, } hVal256s = [8]uint32{ 0x6b08e647, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, } hVal160s = [8]uint32{ 0x6b08e673, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, } ) // Sum512 computes the 512 bit BLAKE2b checksum (or MAC if a key is specified) // of msg and saves the sum in out. The key is optional and can be nil. func Sum512(out *[64]byte, msg, key []byte) { var ( hVal [8]uint64 ctr [2]uint64 block [blake2b.BlockSize]byte off int ) hVal = hVal512 if k := len(key); k > 0 { hVal[0] ^= uint64(k) << 8 // mixin key-length copy(block[:], key) off = blake2b.BlockSize if len(msg) > 0 { blake2b.Core(&hVal, &ctr, blake2b.MsgFlag, block[:]) off = 0 } } if length := len(msg); length > blake2b.BlockSize { n := length & (^(blake2b.BlockSize - 1)) // length -= (length % BlockSize) if length == n { n -= blake2b.BlockSize } blake2b.Core(&hVal, &ctr, blake2b.MsgFlag, msg[:n]) msg = msg[n:] } if len(msg) > 0 { off += copy(block[:], msg) } blake2b.ExtractHash(out, &hVal, &ctr, &block, off) } // Sum256b computes the 256 bit BLAKE2b checksum (or MAC if a key is specified) // of msg and saves the sum in out. The key is optional and can be nil. func Sum256b(out *[32]byte, msg, key []byte) { var ( hVal [8]uint64 ctr [2]uint64 block [blake2b.BlockSize]byte off int out512 [64]byte ) hVal = hVal256b if k := len(key); k > 0 { hVal[0] ^= uint64(k) << 8 // mixin key-length copy(block[:], key) off = blake2b.BlockSize if len(msg) > 0 { blake2b.Core(&hVal, &ctr, blake2b.MsgFlag, block[:]) off = 0 } } if length := len(msg); length > blake2b.BlockSize { n := length & (^(blake2b.BlockSize - 1)) // length -= (length % BlockSize) if length == n { n -= blake2b.BlockSize } blake2b.Core(&hVal, &ctr, blake2b.MsgFlag, msg[:n]) msg = msg[n:] } if len(msg) > 0 { off += copy(block[:], msg) } blake2b.ExtractHash(&out512, &hVal, &ctr, &block, off) copy(out[:], out512[:32]) } // Sum256s computes the 256 bit BLAKE2s checksum (or MAC if a key is specified) // of msg and saves the sum in out. The key is optional and can be nil. func Sum256s(out *[32]byte, msg, key []byte) { var ( hVal [8]uint32 ctr [2]uint32 block [blake2s.BlockSize]byte off int ) hVal = hVal256s if k := len(key); k > 0 { hVal[0] ^= uint32(k) << 8 // mixin key-length copy(block[:], key) off = blake2s.BlockSize if len(msg) > 0 { blake2s.Core(&hVal, &ctr, blake2s.MsgFlag, block[:]) off = 0 } } if length := len(msg); length > blake2s.BlockSize { n := length & (^(blake2s.BlockSize - 1)) // length -= (length % BlockSize) if length == n { n -= blake2s.BlockSize } blake2s.Core(&hVal, &ctr, blake2s.MsgFlag, msg[:n]) msg = msg[n:] } if len(msg) > 0 { off += copy(block[:], msg) } blake2s.ExtractHash(out, &hVal, &ctr, &block, off) } // Sum160s computes the 160 bit BLAKE2s checksum (or MAC if a key is specified) // of msg and saves the sum in out. The key is optional and can be nil. func Sum160s(out *[20]byte, msg, key []byte) { var ( hVal [8]uint32 ctr [2]uint32 block [blake2s.BlockSize]byte off int out256 [32]byte ) hVal = hVal160s if k := len(key); k > 0 { hVal[0] ^= uint32(k) << 8 // mixin key-length copy(block[:], key) off = blake2s.BlockSize if len(msg) > 0 { blake2s.Core(&hVal, &ctr, blake2s.MsgFlag, block[:]) off = 0 } } if length := len(msg); length > blake2s.BlockSize { n := length & (^(blake2s.BlockSize - 1)) // length -= (length % BlockSize) if length == n { n -= blake2s.BlockSize } blake2s.Core(&hVal, &ctr, blake2s.MsgFlag, msg[:n]) msg = msg[n:] } if len(msg) > 0 { off += copy(block[:], msg) } blake2s.ExtractHash(&out256, &hVal, &ctr, &block, off) copy(out[:], out256[:20]) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2_test.go000066400000000000000000000113161520706056300253570ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package blake2 import ( "bytes" "encoding/hex" "testing" "github.com/enceve/crypto/blake2/blake2b" "github.com/enceve/crypto/blake2/blake2s" ) var msgLens = [8]int{0, 63, 64, 65, 127, 128, 129, 1024} var keyLens = [8]int{0, 16, 24, 32} func generateSequence(out []byte, seed uint32) { a := 0xDEAD4BAD * seed b := uint32(1) for i := range out { t := a + b a = b b = t out[i] = byte(t >> 24) } } func TestSum512(t *testing.T) { var sum [64]byte msg := make([]byte, 1024) key := make([]byte, 64) for _, kl := range keyLens { for _, ml := range msgLens { m := msg[:ml] generateSequence(m, uint32(kl+ml)) expected, err := blake2b.Sum(m, 64, nil) if err != nil { t.Fatalf("Failed to compute BLAKE2b sum: %s", err) } Sum512(&sum, m, nil) if !bytes.Equal(sum[:], expected) { t.Fatalf("Unkeyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) } k := key[:kl] generateSequence(k, uint32(ml)) expected, err = blake2b.Sum(m, 64, &blake2b.Config{Key: k}) if err != nil { t.Fatalf("Keyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) } Sum512(&sum, m, k) if !bytes.Equal(sum[:], expected) { t.Fatalf("") } } } } func TestSum256b(t *testing.T) { var sum [32]byte msg := make([]byte, 1024) key := make([]byte, 64) for _, kl := range keyLens { for _, ml := range msgLens { m := msg[:ml] generateSequence(m, uint32(kl+ml)) expected, err := blake2b.Sum(m, 32, nil) if err != nil { t.Fatalf("Failed to compute BLAKE2b sum: %s", err) } Sum256b(&sum, m, nil) if !bytes.Equal(sum[:], expected) { t.Fatalf("Unkeyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) } k := key[:kl] generateSequence(k, uint32(ml)) expected, err = blake2b.Sum(m, 32, &blake2b.Config{Key: k}) if err != nil { t.Fatalf("Keyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) } Sum256b(&sum, m, k) if !bytes.Equal(sum[:], expected) { t.Fatalf("") } } } } func TestSum256s(t *testing.T) { var sum [32]byte msg := make([]byte, 1024) key := make([]byte, 64) for _, kl := range keyLens { for _, ml := range msgLens { m := msg[:ml] generateSequence(m, uint32(kl+ml)) expected, err := blake2s.Sum(m, 32, nil) if err != nil { t.Fatalf("Failed to compute BLAKE2b sum: %s", err) } Sum256s(&sum, m, nil) if !bytes.Equal(sum[:], expected) { t.Fatalf("Unkeyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) } k := key[:kl] generateSequence(k, uint32(ml)) expected, err = blake2s.Sum(m, 32, &blake2s.Config{Key: k}) if err != nil { t.Fatalf("Keyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) } Sum256s(&sum, m, k) if !bytes.Equal(sum[:], expected) { t.Fatalf("") } } } } func TestSum160s(t *testing.T) { var sum [20]byte msg := make([]byte, 1024) key := make([]byte, 64) for _, kl := range keyLens { for _, ml := range msgLens { m := msg[:ml] generateSequence(m, uint32(kl+ml)) expected, err := blake2s.Sum(m, 20, nil) if err != nil { t.Fatalf("Failed to compute BLAKE2b sum: %s", err) } Sum160s(&sum, m, nil) if !bytes.Equal(sum[:], expected) { t.Fatalf("Unkeyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) } k := key[:kl] generateSequence(k, uint32(ml)) expected, err = blake2s.Sum(m, 20, &blake2s.Config{Key: k}) if err != nil { t.Fatalf("Keyed hash values not equal\nFound: %s\nExpected: %s", hex.EncodeToString(sum[:]), hex.EncodeToString(expected)) } Sum160s(&sum, m, k) if !bytes.Equal(sum[:], expected) { t.Fatalf("") } } } } // Benchmarks func benchmarkSum512(b *testing.B, size int) { var sum512 [64]byte buf := make([]byte, size) b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { Sum512(&sum512, buf, nil) } } func benchmarkSum256s(b *testing.B, size int) { var sum256s [32]byte buf := make([]byte, size) b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { Sum256s(&sum256s, buf, nil) } } func BenchmarkSum512_64(b *testing.B) { benchmarkSum512(b, 64) } func BenchmarkSum512_1024(b *testing.B) { benchmarkSum512(b, 1024) } func BenchmarkSum256s_64(b *testing.B) { benchmarkSum256s(b, 64) } func BenchmarkSum256s_1024(b *testing.B) { benchmarkSum256s(b, 1024) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2b/000077500000000000000000000000001520706056300241315ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2b/blake2b.go000066400000000000000000000123651520706056300257710ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package blake2b implements the BLAKE2b hash function. // BLAKE2b produces hash values from 8 to 512 bit (1 to 64 byte), // and can be configured as a MAC. Furthermore BLAKE2b supports // salted/randomized and personalized hashing. // BLAKE2b can process messages up to 2^128 bytes, which is enough // for all practical use cases. package blake2b import ( "errors" "hash" "strconv" "github.com/enceve/crypto" ) const ( // The BLAKE2b block size in bytes. BlockSize = 128 // The max. size of the BLAKE2b checksum Size = 64 ) // Config contains the BLAKE2b configuration: // - Key for computing MACs // - Salt for randomized hashing // - Personal for personalized hashing // All fields are optional and can be nil. type Config struct { Key []byte // The key for MAC (length must between 0 and 64) Salt []byte // The salt (length must between 0 and 16) Personal []byte // The personalization for unique hashing (length must between 0 and 16) } // Configure takes the hash size and the BLAKE2b configuration and // computes the 8 64-bit chain values. The conf is optional and can be nil, // or must be a valid configuraton struct - otherwise a non-nil error is returned. func Configure(hVal *[8]uint64, hashsize int, conf *Config) error { if hashsize <= 0 || hashsize > Size { return errors.New("illegal hash size " + strconv.Itoa(hashsize)) } var key, salt, personal []byte if conf != nil { key = conf.Key salt = conf.Salt personal = conf.Personal } if k := len(key); k > Size { return crypto.KeySizeError(k) } if s := len(salt); s > 16 { return errors.New("illegal salt size " + strconv.Itoa(s)) } if p := len(personal); p > 16 { return errors.New("illegal personalization size " + strconv.Itoa(p)) } var p [BlockSize]byte p[0] = byte(hashsize) p[1] = byte(len(key)) p[2] = 1 p[3] = 1 if len(salt) > 0 { copy(p[32:], salt) } if len(personal) > 0 { copy(p[48:], personal) } for i := range iv { j := i * 8 v := uint64(p[j+0]) | uint64(p[j+1])<<8 | uint64(p[j+2])<<16 | uint64(p[j+3])<<24 | uint64(p[j+4])<<32 | uint64(p[j+5])<<40 | uint64(p[j+6])<<48 | uint64(p[j+7])<<56 hVal[i] = iv[i] ^ v } return nil } // Sum returns the BLAKE2b checksum with the given hash size of msg using the (optional) // conf for configuration. This function returns a non-nil error if the configuration // is invalid. func Sum(msg []byte, hashsize int, conf *Config) ([]byte, error) { h, err := New(hashsize, conf) if err != nil { return nil, err } h.Write(msg) return h.Sum(nil), nil } // New returns a hash.Hash computing the BLAKE2b checksum with the given hash size // using the (optional) conf for configuration. This function returns a non-nil error // if the configuration is invalid. func New(hashsize int, conf *Config) (hash.Hash, error) { h := new(hashFunc) if err := Configure(&(h.hVal), hashsize, conf); err != nil { return nil, err } h.hashsize = hashsize h.hValCpy = h.hVal if conf != nil && len(conf.Key) > 0 { copy(h.key[:], conf.Key) h.block = h.key h.off = BlockSize h.hasKey = true } return h, nil } // ExtractHash takes the 8 64-bit chain values, the 128-bit counter, the 128 byte block // and a block-offset and extracts the checksum to out. func ExtractHash(out *[Size]byte, hVal *[8]uint64, ctr *[2]uint64, block *[BlockSize]byte, off int) { diff := uint64(BlockSize - off) if ctr[0] < diff { ctr[1]-- } ctr[0] -= diff for i := off; i < BlockSize; i++ { block[i] = 0 } Core(hVal, ctr, FinalFlag, block[:]) j := 0 for _, s := range hVal { out[j+0] = byte(s >> 0) out[j+1] = byte(s >> 8) out[j+2] = byte(s >> 16) out[j+3] = byte(s >> 24) out[j+4] = byte(s >> 32) out[j+5] = byte(s >> 40) out[j+6] = byte(s >> 48) out[j+7] = byte(s >> 56) j += 8 } } type hashFunc struct { hashsize int // the hash size in bytes hVal, hValCpy [8]uint64 // the chain values ctr [2]uint64 // the counter (max 2^128 bytes) block [BlockSize]byte // the buffer off int // the buffer offset hasKey bool // flag indicating MAC usage key [BlockSize]byte // the key for MAC } func (h *hashFunc) BlockSize() int { return BlockSize } func (h *hashFunc) Size() int { return h.hashsize } func (h *hashFunc) Write(p []byte) (int, error) { n := len(p) dif := BlockSize - h.off if h.off > 0 && n > dif { h.off += copy(h.block[h.off:], p[:dif]) p = p[dif:] if h.off == BlockSize && len(p) > 0 { Core(&(h.hVal), &(h.ctr), MsgFlag, h.block[:]) h.off = 0 } } if length := len(p); length > BlockSize { nb := length & (^(BlockSize - 1)) // length -= (length % BlockSize) if length == nb { nb -= BlockSize } Core(&(h.hVal), &(h.ctr), MsgFlag, p[:nb]) p = p[nb:] } if len(p) > 0 { h.off += copy(h.block[h.off:], p) } return n, nil } func (h *hashFunc) Reset() { h.hVal = h.hValCpy h.ctr[0], h.ctr[1] = 0, 0 for i := range h.block { h.block[i] = 0 } h.off = 0 if h.hasKey { h.block = h.key h.off = BlockSize } } func (h *hashFunc) Sum(b []byte) []byte { hVal := h.hVal ctr := h.ctr buf := h.block off := h.off var out [Size]byte ExtractHash(&out, &hVal, &ctr, &buf, off) return append(b, out[:h.hashsize]...) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2b/blake2b_ref.go000066400000000000000000000064141520706056300266230ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package blake2b func Core(hVal *[8]uint64, counter *[2]uint64, flag uint64, msg []byte) { h0, h1, h2, h3 := hVal[0], hVal[1], hVal[2], hVal[3] h4, h5, h6, h7 := hVal[4], hVal[5], hVal[6], hVal[7] ctr0 := counter[0] ctr1 := counter[1] var m [16]uint64 length := len(msg) for i := 0; i < length; i += BlockSize { ctr0 += BlockSize if ctr0 < BlockSize { ctr1++ } v0, v1, v2, v3, v4, v5, v6, v7 := h0, h1, h2, h3, h4, h5, h6, h7 v8, v9, v10, v11 := iv[0], iv[1], iv[2], iv[3] v12, v13, v14, v15 := iv[4], iv[5], iv[6], iv[7] v12 ^= ctr0 v13 ^= ctr1 v14 ^= flag j := i for k := range m { m[k] = uint64(msg[j]) | uint64(msg[j+1])<<8 | uint64(msg[j+2])<<16 | uint64(msg[j+3])<<24 | uint64(msg[j+4])<<32 | uint64(msg[j+5])<<40 | uint64(msg[j+6])<<48 | uint64(msg[j+7])<<56 j += 8 } for j := range precomputed { s := &(precomputed[j]) v0 += m[s[0]] v0 += v4 v12 ^= v0 v12 = v12<<(64-32) | v12>>32 v8 += v12 v4 ^= v8 v4 = v4<<(64-24) | v4>>24 v1 += m[s[1]] v1 += v5 v13 ^= v1 v13 = v13<<(64-32) | v13>>32 v9 += v13 v5 ^= v9 v5 = v5<<(64-24) | v5>>24 v2 += m[s[2]] v2 += v6 v14 ^= v2 v14 = v14<<(64-32) | v14>>32 v10 += v14 v6 ^= v10 v6 = v6<<(64-24) | v6>>24 v3 += m[s[3]] v3 += v7 v15 ^= v3 v15 = v15<<(64-32) | v15>>32 v11 += v15 v7 ^= v11 v7 = v7<<(64-24) | v7>>24 v0 += m[s[7]] v0 += v4 v12 ^= v0 v12 = v12<<(64-16) | v12>>16 v8 += v12 v4 ^= v8 v4 = v4<<(64-63) | v4>>63 v1 += m[s[6]] v1 += v5 v13 ^= v1 v13 = v13<<(64-16) | v13>>16 v9 += v13 v5 ^= v9 v5 = v5<<(64-63) | v5>>63 v2 += m[s[4]] v2 += v6 v14 ^= v2 v14 = v14<<(64-16) | v14>>16 v10 += v14 v6 ^= v10 v6 = v6<<(64-63) | v6>>63 v3 += m[s[5]] v3 += v7 v15 ^= v3 v15 = v15<<(64-16) | v15>>16 v11 += v15 v7 ^= v11 v7 = v7<<(64-63) | v7>>63 v0 += m[s[8]] v0 += v5 v15 ^= v0 v15 = v15<<(64-32) | v15>>32 v10 += v15 v5 ^= v10 v5 = v5<<(64-24) | v5>>24 v1 += m[s[9]] v1 += v6 v12 ^= v1 v12 = v12<<(64-32) | v12>>32 v11 += v12 v6 ^= v11 v6 = v6<<(64-24) | v6>>24 v2 += m[s[10]] v2 += v7 v13 ^= v2 v13 = v13<<(64-32) | v13>>32 v8 += v13 v7 ^= v8 v7 = v7<<(64-24) | v7>>24 v3 += m[s[11]] v3 += v4 v14 ^= v3 v14 = v14<<(64-32) | v14>>32 v9 += v14 v4 ^= v9 v4 = v4<<(64-24) | v4>>24 v0 += m[s[15]] v0 += v5 v15 ^= v0 v15 = v15<<(64-16) | v15>>16 v10 += v15 v5 ^= v10 v5 = v5<<(64-63) | v5>>63 v1 += m[s[14]] v1 += v6 v12 ^= v1 v12 = v12<<(64-16) | v12>>16 v11 += v12 v6 ^= v11 v6 = v6<<(64-63) | v6>>63 v2 += m[s[12]] v2 += v7 v13 ^= v2 v13 = v13<<(64-16) | v13>>16 v8 += v13 v7 ^= v8 v7 = v7<<(64-63) | v7>>63 v3 += m[s[13]] v3 += v4 v14 ^= v3 v14 = v14<<(64-16) | v14>>16 v9 += v14 v4 ^= v9 v4 = v4<<(64-63) | v4>>63 } h0 ^= v0 ^ v8 h1 ^= v1 ^ v9 h2 ^= v2 ^ v10 h3 ^= v3 ^ v11 h4 ^= v4 ^ v12 h5 ^= v5 ^ v13 h6 ^= v6 ^ v14 h7 ^= v7 ^ v15 } hVal[0], hVal[1], hVal[2], hVal[3] = h0, h1, h2, h3 hVal[4], hVal[5], hVal[6], hVal[7] = h4, h5, h6, h7 counter[0] = ctr0 counter[1] = ctr1 } golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2b/blake2b_test.go000066400000000000000000000070161520706056300270250ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package blake2b import ( "testing" ) func TestBlockSize(t *testing.T) { h, err := New(64, nil) if err != nil { t.Fatalf("Failed to create BLAKE2b instance: %s", err) } if bs := h.BlockSize(); bs != BlockSize { t.Fatalf("BlockSize() returned: %d - but expected: %d", bs, BlockSize) } } func TestSize(t *testing.T) { h, err := New(64, nil) if err != nil { t.Fatalf("Failed to create BLAKE2b instance: %s", err) } if s := h.Size(); s != 64 { t.Fatalf("Size() returned: %d - but expected: %d", s, 64) } h, err = New(32, nil) if err != nil { t.Fatalf("Failed to create BLAKE2b instance: %s", err) } if s := h.Size(); s != 32 { t.Fatalf("Size() returned: %d - but expected: %d", s, 64) } } func TestReset(t *testing.T) { h, err := New(32, &Config{ Key: make([]byte, 64), Salt: make([]byte, 16), Personal: make([]byte, 8), }) if err != nil { t.Fatalf("Failed to create BLAKE2b instance: %s", err) } s, ok := h.(*hashFunc) if !ok { t.Fatal("Impossible situation: New returns no blake2b struct") } orig := *s // copy s.Write(make([]byte, (2*BlockSize)+1)) s.Reset() if s.hVal != orig.hVal { t.Fatalf("Reseted hVal field: %v - but expected: %v", s.hVal, orig.hVal) } if s.hValCpy != orig.hValCpy { t.Fatalf("Reseted hValCpy field: %v - but expected: %v", s.hValCpy, orig.hValCpy) } if s.block != orig.block { t.Fatalf("Reseted block field: %v - but expected: %v", s.block, orig.block) } if s.ctr != orig.ctr { t.Fatalf("Reseted ctr field: %v - but expected: %v", s.ctr, orig.ctr) } if s.key != orig.key { t.Fatalf("Reseted key field: %v - but expected: %v", s.key, orig.key) } if s.off != orig.off { t.Fatalf("Reseted off field %d - but expected %d", s.off, orig.off) } if s.hasKey != orig.hasKey { t.Fatalf("Reseted hasKey field %v - but expected %v", s.hasKey, orig.hasKey) } } func TestNew(t *testing.T) { _, err := New(0, nil) if err == nil { t.Fatal("New allowed 0 for hash size") } } func TestSum(t *testing.T) { _, err := Sum(nil, 0, nil) if err == nil { t.Fatal("Sum allowed 0 for hash size") } } func TestConfigure(t *testing.T) { var hval [8]uint64 err := Configure(&hval, 0, nil) if err == nil { t.Fatal("Configure allowed 0 for hash size") } err = Configure(&hval, Size+1, nil) if err == nil { t.Fatalf("Configure allowed %d for hash size", Size+1) } err = Configure(&hval, Size, &Config{Key: make([]byte, Size+1)}) if err == nil { t.Fatalf("Configure allowed key with length %d", Size+1) } err = Configure(&hval, Size, &Config{Salt: make([]byte, 17)}) if err == nil { t.Fatalf("Configure allowed salt with length %d", 17) } err = Configure(&hval, Size, &Config{Personal: make([]byte, 17)}) if err == nil { t.Fatalf("Configure allowed personal with length %d", 17) } } // Benchmarks func benchmarkWrite(b *testing.B, size int) { h, err := New(64, nil) if err != nil { b.Fatalf("Failed to create BLAKE2s instance: %s", err) } buf := make([]byte, size) b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { h.Write(buf) } } func benchmarkSum(b *testing.B, size int) { buf := make([]byte, size) b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { Sum(buf, 64, nil) } } func BenchmarkWrite_64(b *testing.B) { benchmarkWrite(b, 64) } func BenchmarkWrite_1K(b *testing.B) { benchmarkWrite(b, 1024) } func BenchmarkSum_64(b *testing.B) { benchmarkSum(b, 64) } func BenchmarkSum_1K(b *testing.B) { benchmarkSum(b, 1024) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2b/constants.go000066400000000000000000000025701520706056300265000ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package blake2b const ( // The block flag for message blocks MsgFlag uint64 = 0 // The block flag for the last block FinalFlag uint64 = 0xffffffffffffffff ) // the blake2b iv constants var iv = [8]uint64{ 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, } // the precomputed values for blake2b // there are 12 16-byte arrays - one for each round // the entries are calculated from the sigma constants. var precomputed [12][16]byte = [12][16]byte{ {0, 2, 4, 6, 5, 7, 3, 1, 8, 10, 12, 14, 13, 15, 11, 9}, {14, 4, 9, 13, 15, 6, 8, 10, 1, 0, 11, 5, 7, 3, 2, 12}, {11, 12, 5, 15, 2, 13, 0, 8, 10, 3, 7, 9, 1, 4, 6, 14}, {7, 3, 13, 11, 12, 14, 1, 9, 2, 5, 4, 15, 0, 8, 10, 6}, {9, 5, 2, 10, 4, 15, 7, 0, 14, 11, 6, 3, 8, 13, 12, 1}, {2, 6, 0, 8, 11, 3, 10, 12, 4, 7, 15, 1, 14, 9, 5, 13}, {12, 1, 14, 4, 13, 10, 15, 5, 0, 6, 9, 8, 2, 11, 3, 7}, {13, 7, 12, 3, 1, 9, 14, 11, 5, 15, 8, 2, 6, 10, 4, 0}, {6, 14, 11, 0, 3, 8, 9, 15, 12, 13, 1, 10, 4, 5, 7, 2}, {10, 8, 7, 1, 6, 5, 4, 2, 15, 9, 3, 13, 12, 0, 14, 11}, {0, 2, 4, 6, 5, 7, 3, 1, 8, 10, 12, 14, 13, 15, 11, 9}, // equal to the first {14, 4, 9, 13, 15, 6, 8, 10, 1, 0, 11, 5, 7, 3, 2, 12}, // equal to the secound } golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2b/vectors_test.go000066400000000000000000000135701520706056300272120ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package blake2b import ( "bytes" "encoding/hex" "testing" ) func fromHex(s string) []byte { b, err := hex.DecodeString(s) if err != nil { panic(err) } return b } var testVectors = []struct { hashsize int conf *Config msg, hash string }{ // Test vector https://tools.ietf.org/html/rfc7693#appendix-A { hashsize: 64, msg: hex.EncodeToString([]byte("abc")), hash: "BA80A53F981C4D0D6A2797B69F12F6E94C212F14685AC4B74B12BB6FDBFFA2D1" + "7D87C5392AAB792DC252D5DE4533CC9518D38AA8DBF1925AB92386EDD4009923", }, // Test vectors from https://blake2.net/blake2b-test.txt { hashsize: 64, conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f10111213141" + "5161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343" + "5363738393a3b3c3d3e3f")}, msg: hex.EncodeToString([]byte("")), hash: "10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786" + "b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568", }, { hashsize: 64, conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f1011121314151617181" + "91a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a" + "3b3c3d3e3f")}, msg: "00", hash: "961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4" + "187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd", }, { hashsize: 64, conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f1011121314151617181" + "91a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a" + "3b3c3d3e3f")}, msg: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2" + "02122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", hash: "65676d800617972fbd87e4b9514e1c67402b7a331096d3bfac22f1abb95374ab" + "c942f16e9ab0ead33b87c91968a6e509e119ff07787b3ef483e1dcdccf6e3022", }, { hashsize: 64, conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f10111213141516171819" + "1a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b" + "3c3d3e3f")}, msg: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4" + "04142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60" + "6162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808" + "182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1" + "a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c" + "2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2" + "e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfd", hash: "d444bfa2362a96df213d070e33fa841f51334e4e76866b8139e8af3bb3398be2" + "dfaddcbc56b9146de9f68118dc5829e74b0c28d7711907b121f9161cb92b69a9", }, { hashsize: 64, conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f10111213141516171819" + "1a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b" + "3c3d3e3f")}, msg: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2" + "02122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424" + "34445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364656" + "66768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384858687888" + "98a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaaba" + "cadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcec" + "fd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f" + "2f3f4f5f6f7f8f9fafbfcfdfe", hash: "142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e9248" + "4be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461", }, } func TestVectors(t *testing.T) { for i, v := range testVectors { h, err := New(v.hashsize, v.conf) if err != nil { t.Fatalf("Test vector %d : Failed to create new BLAKE2b instance: %s", i, err) } msg := fromHex(v.msg) expSum := fromHex(v.hash) h.Write(msg) sum := h.Sum(nil) if !bytes.Equal(sum, expSum) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(expSum)) } sum, err = Sum(msg, v.hashsize, v.conf) if err != nil { t.Fatalf("Test vector %d : function Sum failed: %s", i, err) } if !bytes.Equal(sum, expSum) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(expSum)) } } } func generateSequence(out []byte, seed uint32) { a := 0xDEAD4BAD * seed // prime b := uint32(1) for i := range out { // fill the buf t := a + b a = b b = t out[i] = byte(t >> 24) } } func TestSelfTest(t *testing.T) { var result = [32]byte{ 0xC2, 0x3A, 0x78, 0x00, 0xD9, 0x81, 0x23, 0xBD, 0x10, 0xF5, 0x06, 0xC6, 0x1E, 0x29, 0xDA, 0x56, 0x03, 0xD7, 0x63, 0xB8, 0xBB, 0xAD, 0x2E, 0x73, 0x7F, 0x5E, 0x76, 0x5A, 0x7B, 0xCC, 0xD4, 0x75, } var hashLens = [4]int{20, 32, 48, 64} var msgLens = [6]int{0, 3, 128, 129, 255, 1024} msg := make([]byte, 1024) key := make([]byte, 64) h, err := New(32, nil) if err != nil { t.Fatalf("Failed to create BLAKE2b instance: %s", err) } for _, hashsize := range hashLens { for _, msgLength := range msgLens { generateSequence(msg[:msgLength], uint32(msgLength)) // unkeyed hash md, err := Sum(msg[:msgLength], hashsize, nil) if err != nil { t.Fatalf("Selftest failed: Failed to compute unkeyed hash: %s", err) } h.Write(md) generateSequence(key[:], uint32(hashsize)) // keyed hash md, err = Sum(msg[:msgLength], hashsize, &Config{Key: key[:hashsize]}) if err != nil { t.Fatalf("Selftest failed: Failed to compute keyed hash: %s", err) } h.Write(md) } } sum := h.Sum(nil) if !bytes.Equal(sum, result[:]) { t.Fatalf("Selftest failed:\nFound: %s\nExpected: %s", hex.EncodeToString(sum), hex.EncodeToString(result[:])) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2s/000077500000000000000000000000001520706056300241525ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2s/blake2s.go000066400000000000000000000120611520706056300260240ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package blake2s implements the BLAKE2s hash function. // BLAKE2s produces hash values from 8 to 256 bit (1 to 32 byte), // and can be configured as a MAC. Furthermore BLAKE2s supports // salted/randomized and personalized hashing. // BLAKE2s can process messages up to 2^64 bytes, which is enough // for almost all practical use cases. package blake2s import ( "errors" "hash" "strconv" "github.com/enceve/crypto" ) const ( // The BLAKE2s block size in bytes. BlockSize = 64 // The max. size of the BLAKE2s checksum Size = 32 ) // Config contains the BLAKE2s configuration: // - Key for computing MACs // - Salt for randomized hashing // - Personal for personalized hashing // All fields are optional and can be nil. type Config struct { Key []byte // The key for MAC (length must between 0 and 32) Salt []byte // The salt (length must between 0 and 8) Personal []byte // The personalization for unique hashing (length must between 0 and 16) } // Configure takes the hash size and the BLAKE2s configuration and // computes the 8 32-bit chain values. The conf is optional and can be nil, // or must be a valid configuraton struct - otherwise a non-nil error is returned. func Configure(hVal *[8]uint32, hashsize int, conf *Config) error { if hashsize <= 0 || hashsize > Size { return errors.New("illegal hash size " + strconv.Itoa(hashsize)) } var key, salt, personal []byte if conf != nil { key = conf.Key salt = conf.Salt personal = conf.Personal } if k := len(key); k > Size { return crypto.KeySizeError(k) } if s := len(salt); s > 8 { return errors.New("illegal salt size " + strconv.Itoa(s)) } if p := len(personal); p > 8 { return errors.New("illegal personalization size " + strconv.Itoa(p)) } var p [BlockSize]byte p[0] = byte(hashsize) p[1] = byte(len(key)) p[2] = 1 p[3] = 1 if len(salt) > 0 { copy(p[16:], salt) } if len(personal) > 0 { copy(p[24:], personal) } for i := range iv { j := i * 4 v := uint32(p[j+0]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24 hVal[i] = iv[i] ^ v } return nil } // Sum returns the BLAKE2s checksum with the given hash size of msg using the (optional) // conf for configuration. This function returns a non-nil error if the configuration // is invalid. func Sum(msg []byte, hashsize int, conf *Config) ([]byte, error) { h, err := New(hashsize, conf) if err != nil { return nil, err } h.Write(msg) return h.Sum(nil), nil } // New returns a hash.Hash computing the BLAKE2s checksum with the given hash size // using the (optional) conf for configuration. This function returns a non-nil error // if the configuration is invalid. func New(hashsize int, conf *Config) (hash.Hash, error) { h := new(hashFunc) if err := Configure(&(h.hVal), hashsize, conf); err != nil { return nil, err } h.hashsize = hashsize h.hValCpy = h.hVal if conf != nil && len(conf.Key) > 0 { copy(h.key[:], conf.Key) h.block = h.key h.off = BlockSize h.hasKey = true } return h, nil } // ExtractHash takes the 8 32-bit chain values, the 64-bit counter, the 64 byte block // and a block-offset and extracts the checksum to out. func ExtractHash(out *[Size]byte, hVal *[8]uint32, ctr *[2]uint32, block *[BlockSize]byte, off int) { diff := uint32(BlockSize - off) if ctr[0] < diff { ctr[1]-- } ctr[0] -= diff for i := off; i < BlockSize; i++ { block[i] = 0 } Core(hVal, ctr, FinalFlag, block[:]) j := 0 for _, s := range hVal { out[j+0] = byte(s >> 0) out[j+1] = byte(s >> 8) out[j+2] = byte(s >> 16) out[j+3] = byte(s >> 24) j += 4 } } type hashFunc struct { hashsize int // the hash size in bytes hVal, hValCpy [8]uint32 // the chain values ctr [2]uint32 // the counter (max 2^64 bytes) block [BlockSize]byte // the buffer off int // the buffer offset hasKey bool // flag indicating MAC usage key [BlockSize]byte // the key for MAC } func (h *hashFunc) BlockSize() int { return BlockSize } func (h *hashFunc) Size() int { return h.hashsize } func (h *hashFunc) Write(p []byte) (int, error) { n := len(p) dif := BlockSize - h.off if h.off > 0 && n > dif { h.off += copy(h.block[h.off:], p[:dif]) p = p[dif:] if h.off == BlockSize && len(p) > 0 { Core(&(h.hVal), &(h.ctr), MsgFlag, h.block[:]) h.off = 0 } } if length := len(p); length > BlockSize { nb := length & (^(BlockSize - 1)) // length -= (length % BlockSize) if length == nb { nb -= BlockSize } Core(&(h.hVal), &(h.ctr), MsgFlag, p[:nb]) p = p[nb:] } if len(p) > 0 { h.off += copy(h.block[h.off:], p) } return n, nil } func (h *hashFunc) Reset() { h.hVal = h.hValCpy h.ctr[0], h.ctr[1] = 0, 0 for i := range h.block { h.block[i] = 0 } h.off = 0 if h.hasKey { h.block = h.key h.off = BlockSize } } func (h *hashFunc) Sum(b []byte) []byte { hVal := h.hVal ctr := h.ctr buf := h.block off := h.off var out [Size]byte ExtractHash(&out, &hVal, &ctr, &buf, off) return append(b, out[:h.hashsize]...) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2s/blake2s_ref.go000066400000000000000000000062141520706056300266630ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package blake2s func Core(hVal *[8]uint32, counter *[2]uint32, flag uint32, msg []byte) { h0, h1, h2, h3 := hVal[0], hVal[1], hVal[2], hVal[3] h4, h5, h6, h7 := hVal[4], hVal[5], hVal[6], hVal[7] ctr0 := counter[0] ctr1 := counter[1] var m [16]uint32 length := len(msg) for i := 0; i < length; i += BlockSize { ctr0 += BlockSize if ctr0 < BlockSize { ctr1++ } v0, v1, v2, v3, v4, v5, v6, v7 := h0, h1, h2, h3, h4, h5, h6, h7 v8, v9, v10, v11 := iv[0], iv[1], iv[2], iv[3] v12, v13, v14, v15 := iv[4], iv[5], iv[6], iv[7] v12 ^= ctr0 v13 ^= ctr1 v14 ^= flag j := i for k := range m { m[k] = uint32(msg[j]) | uint32(msg[j+1])<<8 | uint32(msg[j+2])<<16 | uint32(msg[j+3])<<24 j += 4 } for k := range precomputed { s := &(precomputed[k]) v0 += m[s[0]] v0 += v4 v12 ^= v0 v12 = v12<<(32-16) | v12>>16 v8 += v12 v4 ^= v8 v4 = v4<<(32-12) | v4>>12 v1 += m[s[1]] v1 += v5 v13 ^= v1 v13 = v13<<(32-16) | v13>>16 v9 += v13 v5 ^= v9 v5 = v5<<(32-12) | v5>>12 v2 += m[s[2]] v2 += v6 v14 ^= v2 v14 = v14<<(32-16) | v14>>16 v10 += v14 v6 ^= v10 v6 = v6<<(32-12) | v6>>12 v3 += m[s[3]] v3 += v7 v15 ^= v3 v15 = v15<<(32-16) | v15>>16 v11 += v15 v7 ^= v11 v7 = v7<<(32-12) | v7>>12 v0 += m[s[7]] v0 += v4 v12 ^= v0 v12 = v12<<(32-8) | v12>>8 v8 += v12 v4 ^= v8 v4 = v4<<(32-7) | v4>>7 v1 += m[s[6]] v1 += v5 v13 ^= v1 v13 = v13<<(32-8) | v13>>8 v9 += v13 v5 ^= v9 v5 = v5<<(32-7) | v5>>7 v2 += m[s[4]] v2 += v6 v14 ^= v2 v14 = v14<<(32-8) | v14>>8 v10 += v14 v6 ^= v10 v6 = v6<<(32-7) | v6>>7 v3 += m[s[5]] v3 += v7 v15 ^= v3 v15 = v15<<(32-8) | v15>>8 v11 += v15 v7 ^= v11 v7 = v7<<(32-7) | v7>>7 v0 += m[s[8]] v0 += v5 v15 ^= v0 v15 = v15<<(32-16) | v15>>16 v10 += v15 v5 ^= v10 v5 = v5<<(32-12) | v5>>12 v1 += m[s[9]] v1 += v6 v12 ^= v1 v12 = v12<<(32-16) | v12>>16 v11 += v12 v6 ^= v11 v6 = v6<<(32-12) | v6>>12 v2 += m[s[10]] v2 += v7 v13 ^= v2 v13 = v13<<(32-16) | v13>>16 v8 += v13 v7 ^= v8 v7 = v7<<(32-12) | v7>>12 v3 += m[s[11]] v3 += v4 v14 ^= v3 v14 = v14<<(32-16) | v14>>16 v9 += v14 v4 ^= v9 v4 = v4<<(32-12) | v4>>12 v0 += m[s[15]] v0 += v5 v15 ^= v0 v15 = v15<<(32-8) | v15>>8 v10 += v15 v5 ^= v10 v5 = v5<<(32-7) | v5>>7 v1 += m[s[14]] v1 += v6 v12 ^= v1 v12 = v12<<(32-8) | v12>>8 v11 += v12 v6 ^= v11 v6 = v6<<(32-7) | v6>>7 v2 += m[s[12]] v2 += v7 v13 ^= v2 v13 = v13<<(32-8) | v13>>8 v8 += v13 v7 ^= v8 v7 = v7<<(32-7) | v7>>7 v3 += m[s[13]] v3 += v4 v14 ^= v3 v14 = v14<<(32-8) | v14>>8 v9 += v14 v4 ^= v9 v4 = v4<<(32-7) | v4>>7 } h0 ^= v0 ^ v8 h1 ^= v1 ^ v9 h2 ^= v2 ^ v10 h3 ^= v3 ^ v11 h4 ^= v4 ^ v12 h5 ^= v5 ^ v13 h6 ^= v6 ^ v14 h7 ^= v7 ^ v15 } hVal[0], hVal[1], hVal[2], hVal[3] = h0, h1, h2, h3 hVal[4], hVal[5], hVal[6], hVal[7] = h4, h5, h6, h7 counter[0] = ctr0 counter[1] = ctr1 } golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2s/blake2s_test.go000066400000000000000000000070111520706056300270620ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package blake2s import ( "testing" ) func TestBlockSize(t *testing.T) { h, err := New(32, nil) if err != nil { t.Fatalf("Failed to create BLAKE2s instance: %s", err) } if bs := h.BlockSize(); bs != BlockSize { t.Fatalf("BlockSize() returned: %d - but expected: %d", bs, BlockSize) } } func TestSize(t *testing.T) { h, err := New(32, nil) if err != nil { t.Fatalf("Failed to create BLAKE2s instance: %s", err) } if s := h.Size(); s != 32 { t.Fatalf("Size() returned: %d - but expected: %d", s, 32) } h, err = New(20, nil) if err != nil { t.Fatalf("Failed to create BLAKE2s instance: %s", err) } if s := h.Size(); s != 20 { t.Fatalf("Size() returned: %d - but expected: %d", s, 20) } } func TestReset(t *testing.T) { h, err := New(32, &Config{ Key: make([]byte, 32), Salt: make([]byte, 8), Personal: make([]byte, 4), }) if err != nil { t.Fatalf("Failed to create BLAKE2s instance: %s", err) } s, ok := h.(*hashFunc) if !ok { t.Fatal("Impossible situation: New returns no blake2s struct") } orig := *s // copy s.Write(make([]byte, (2*BlockSize)+1)) s.Reset() if s.hVal != orig.hVal { t.Fatalf("Reseted hVal field: %v - but expected: %v", s.hVal, orig.hVal) } if s.hValCpy != orig.hValCpy { t.Fatalf("Reseted hValCpy field: %v - but expected: %v", s.hValCpy, orig.hValCpy) } if s.block != orig.block { t.Fatalf("Reseted block field: %v - but expected: %v", s.block, orig.block) } if s.ctr != orig.ctr { t.Fatalf("Reseted ctr field: %v - but expected: %v", s.ctr, orig.ctr) } if s.key != orig.key { t.Fatalf("Reseted key field: %v - but expected: %v", s.key, orig.key) } if s.off != orig.off { t.Fatalf("Reseted off field %d - but expected %d", s.off, orig.off) } if s.hasKey != orig.hasKey { t.Fatalf("Reseted hasKey field %v - but expected %v", s.hasKey, orig.hasKey) } } func TestNew(t *testing.T) { _, err := New(0, nil) if err == nil { t.Fatal("New allowed 0 for hash size") } } func TestSum(t *testing.T) { _, err := Sum(nil, 0, nil) if err == nil { t.Fatal("Sum allowed 0 for hash size") } } func TestConfigure(t *testing.T) { var hval [8]uint32 err := Configure(&hval, 0, nil) if err == nil { t.Fatal("Configure allowed 0 for hash size") } err = Configure(&hval, Size+1, nil) if err == nil { t.Fatalf("Configure allowed %d for hash size", Size+1) } err = Configure(&hval, Size, &Config{Key: make([]byte, Size+1)}) if err == nil { t.Fatalf("Configure allowed key with length %d", Size+1) } err = Configure(&hval, Size, &Config{Salt: make([]byte, 9)}) if err == nil { t.Fatalf("Configure allowed salt with length %d", 9) } err = Configure(&hval, Size, &Config{Personal: make([]byte, 9)}) if err == nil { t.Fatalf("Configure allowed personal with length %d", 9) } } // Benchmarks func benchmarkWrite(b *testing.B, size int) { h, err := New(32, nil) if err != nil { b.Fatalf("Failed to create BLAKE2s instance: %s", err) } buf := make([]byte, size) b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { h.Write(buf) } } func benchmarkSum(b *testing.B, size int) { buf := make([]byte, size) b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { Sum(buf, 32, nil) } } func BenchmarkWrite_64(b *testing.B) { benchmarkWrite(b, 64) } func BenchmarkWrite_1K(b *testing.B) { benchmarkWrite(b, 1024) } func BenchmarkSum_64(b *testing.B) { benchmarkSum(b, 64) } func BenchmarkSum_1K(b *testing.B) { benchmarkSum(b, 1024) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2s/constants.go000066400000000000000000000022141520706056300265140ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package blake2s const ( // The block flag for message blocks MsgFlag uint32 = 0 // The block flag for the last block FinalFlag uint32 = 0xffffffff ) // the BLAKE2s iv constants var iv = [8]uint32{ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, } // the precomputed values for BLAKE2s // there are 12 16-byte arrays - one for each round // the entries are calculated from the sigma constants. var precomputed [10][16]byte = [10][16]byte{ {0, 2, 4, 6, 5, 7, 3, 1, 8, 10, 12, 14, 13, 15, 11, 9}, {14, 4, 9, 13, 15, 6, 8, 10, 1, 0, 11, 5, 7, 3, 2, 12}, {11, 12, 5, 15, 2, 13, 0, 8, 10, 3, 7, 9, 1, 4, 6, 14}, {7, 3, 13, 11, 12, 14, 1, 9, 2, 5, 4, 15, 0, 8, 10, 6}, {9, 5, 2, 10, 4, 15, 7, 0, 14, 11, 6, 3, 8, 13, 12, 1}, {2, 6, 0, 8, 11, 3, 10, 12, 4, 7, 15, 1, 14, 9, 5, 13}, {12, 1, 14, 4, 13, 10, 15, 5, 0, 6, 9, 8, 2, 11, 3, 7}, {13, 7, 12, 3, 1, 9, 14, 11, 5, 15, 8, 2, 6, 10, 4, 0}, {6, 14, 11, 0, 3, 8, 9, 15, 12, 13, 1, 10, 4, 5, 7, 2}, {10, 8, 7, 1, 6, 5, 4, 2, 15, 9, 3, 13, 12, 0, 14, 11}, } golang-github-enceve-crypto-0.0~git20160707.34d48bb/blake2/blake2s/vectors_test.go000066400000000000000000000106051520706056300272270ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package blake2s import ( "bytes" "encoding/hex" "testing" ) func fromHex(s string) []byte { b, err := hex.DecodeString(s) if err != nil { panic(err) } return b } var vectors = []struct { hashsize int conf *Config msg, hash string }{ // Test vectors from https://blake2.net/blake2s-test.txt { hashsize: 32, conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")}, msg: hex.EncodeToString([]byte("")), hash: "48a8997da407876b3d79c0d92325ad3b89cbb754d86ab71aee047ad345fd2c49", }, { hashsize: 32, conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")}, msg: "00", hash: "40d15fee7c328830166ac3f918650f807e7e01e177258cdc0a39b11f598066f1", }, { hashsize: 32, conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")}, msg: "000102030405060708090a", hash: "e33c4c9bd0cc7e45c80e65c77fa5997fec7002738541509e68a9423891e822a3", }, { hashsize: 32, conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")}, msg: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", hash: "c03bc642b20959cbe133a0303e0c1abff3e31ec8e1a328ec8565c36decff5265", }, { hashsize: 32, conf: &Config{Key: fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")}, msg: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414" + "2434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364" + "65666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868" + "788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9" + "aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbc" + "ccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedee" + "eff0f1f2f3f4f5f6f7f8f9fafbfcfdfe", hash: "3fb735061abc519dfe979e54c1ee5bfad0a9d858b3315bad34bde999efd724dd", }, } func TestVectors(t *testing.T) { for i, v := range vectors { h, err := New(v.hashsize, v.conf) if err != nil { t.Fatalf("Test vector %d : Failed to create new BLAKE2s instance: %s", i, err) } msg := fromHex(v.msg) expSum := fromHex(v.hash) h.Write(msg) sum := h.Sum(nil) if !bytes.Equal(sum, expSum) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(expSum)) } sum, err = Sum(msg, v.hashsize, v.conf) if err != nil { t.Fatalf("Test vector %d : function Sum failed: %s", i, err) } if !bytes.Equal(sum, expSum) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(expSum)) } } } func generateSequence(out []byte, seed uint32) { a := 0xDEAD4BAD * seed // prime b := uint32(1) for i := range out { // fill the buf t := a + b a = b b = t out[i] = byte(t >> 24) } } // BLAKE2s self-test validation from // https://tools.ietf.org/html/rfc7693#appendix-E func TestSelfTest(t *testing.T) { var result = [32]byte{ 0x6A, 0x41, 0x1F, 0x08, 0xCE, 0x25, 0xAD, 0xCD, 0xFB, 0x02, 0xAB, 0xA6, 0x41, 0x45, 0x1C, 0xEC, 0x53, 0xC5, 0x98, 0xB2, 0x4F, 0x4F, 0xC7, 0x87, 0xFB, 0xDC, 0x88, 0x79, 0x7F, 0x4C, 0x1D, 0xFE, } var hashLens = [4]int{16, 20, 28, 32} var msgLens = [6]int{0, 3, 64, 65, 255, 1024} msg := make([]byte, 1024) key := make([]byte, 32) h, err := New(32, nil) if err != nil { t.Fatalf("Failed to create BLAKE2s instance: %s", err) } for _, hashsize := range hashLens { for _, msgLength := range msgLens { generateSequence(msg[:msgLength], uint32(msgLength)) // unkeyed hash md, err := Sum(msg[:msgLength], hashsize, nil) if err != nil { t.Fatalf("Selftest failed: Failed to compute unkeyed hash: %s", err) } h.Write(md) generateSequence(key[:], uint32(hashsize)) // keyed hash md, err = Sum(msg[:msgLength], hashsize, &Config{Key: key[:hashsize]}) if err != nil { t.Fatalf("Selftest failed: Failed to compute keyed hash: %s", err) } h.Write(md) } } sum := h.Sum(nil) if !bytes.Equal(sum, result[:]) { t.Fatalf("Selftest failed:\nFound: %s\nExpected: %s", hex.EncodeToString(sum), hex.EncodeToString(result[:])) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/camellia/000077500000000000000000000000001520706056300232365ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/camellia/camellia.go000066400000000000000000000345471520706056300253510ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package camellia implements the camellia block cipher. // The cipher has block size of 128 bit (16 byte) and // accepts 128, 192 or 256 bit keys (16, 24, 32 byte). // Camellia was jointly developed by Mitsubishi Electric // and NTT of Japan. // Camellia was added to many crypto protocols (e.g. TLS). package camellia import ( "crypto/cipher" "github.com/enceve/crypto" ) // The block size of the camellia block cipher in bytes. const BlockSize = 16 // NewCipher returns a new cipher.Block implementing the camellia cipher. // The key argument must be 128, 192 or 256 bit (16, 24, 32 byte). func NewCipher(key []byte) (cipher.Block, error) { k := len(key) if k == 16 { c := new(blockCipher128) c.keySchedule(key) return c, nil } if k == 24 || k == 32 { c := new(blockCipher256) c.keySchedule(key) return c, nil } return nil, crypto.KeySizeError(k) } // The camellia cipher for 128 bit keys. type blockCipher128 struct { sk [52]uint32 // The 52 32-bit subkeys } func (c *blockCipher128) BlockSize() int { return BlockSize } func (c *blockCipher128) Encrypt(dst, src []byte) { if len(src) < BlockSize { panic("camellia: src buffer to small") } if len(dst) < BlockSize { panic("camellia: dst buffer to small") } r0 := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3]) r1 := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7]) r2 := uint32(src[8])<<24 | uint32(src[9])<<16 | uint32(src[10])<<8 | uint32(src[11]) r3 := uint32(src[12])<<24 | uint32(src[13])<<16 | uint32(src[14])<<8 | uint32(src[15]) k := &(c.sk) r0 ^= k[0] r1 ^= k[1] r2 ^= k[2] r3 ^= k[3] f(&r0, &r1, &r2, &r3, k[4], k[5]) f(&r2, &r3, &r0, &r1, k[6], k[7]) f(&r0, &r1, &r2, &r3, k[8], k[9]) f(&r2, &r3, &r0, &r1, k[10], k[11]) f(&r0, &r1, &r2, &r3, k[12], k[13]) f(&r2, &r3, &r0, &r1, k[14], k[15]) t := r0 & k[16] r1 ^= (t << 1) | (t >> (32 - 1)) r2 ^= r3 | k[19] r0 ^= r1 | k[17] t = r2 & k[18] r3 ^= (t << 1) | (t >> (32 - 1)) f(&r0, &r1, &r2, &r3, k[20], k[21]) f(&r2, &r3, &r0, &r1, k[22], k[23]) f(&r0, &r1, &r2, &r3, k[24], k[25]) f(&r2, &r3, &r0, &r1, k[26], k[27]) f(&r0, &r1, &r2, &r3, k[28], k[29]) f(&r2, &r3, &r0, &r1, k[30], k[31]) t = r0 & k[32] r1 ^= (t << 1) | (t >> (32 - 1)) r2 ^= r3 | k[35] r0 ^= r1 | k[33] t = r2 & k[34] r3 ^= (t << 1) | (t >> (32 - 1)) f(&r0, &r1, &r2, &r3, k[36], k[37]) f(&r2, &r3, &r0, &r1, k[38], k[39]) f(&r0, &r1, &r2, &r3, k[40], k[41]) f(&r2, &r3, &r0, &r1, k[42], k[43]) f(&r0, &r1, &r2, &r3, k[44], k[45]) f(&r2, &r3, &r0, &r1, k[46], k[47]) r2 ^= k[48] r3 ^= k[49] r0 ^= k[50] r1 ^= k[51] dst[0] = byte(r2 >> 24) dst[1] = byte(r2 >> 16) dst[2] = byte(r2 >> 8) dst[3] = byte(r2) dst[4] = byte(r3 >> 24) dst[5] = byte(r3 >> 16) dst[6] = byte(r3 >> 8) dst[7] = byte(r3) dst[8] = byte(r0 >> 24) dst[9] = byte(r0 >> 16) dst[10] = byte(r0 >> 8) dst[11] = byte(r0) dst[12] = byte(r1 >> 24) dst[13] = byte(r1 >> 16) dst[14] = byte(r1 >> 8) dst[15] = byte(r1) } func (c *blockCipher128) Decrypt(dst, src []byte) { if len(src) < BlockSize { panic("camellia: src buffer to small") } if len(dst) < BlockSize { panic("camellia: dst buffer to small") } r0 := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3]) r1 := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7]) r2 := uint32(src[8])<<24 | uint32(src[9])<<16 | uint32(src[10])<<8 | uint32(src[11]) r3 := uint32(src[12])<<24 | uint32(src[13])<<16 | uint32(src[14])<<8 | uint32(src[15]) k := &(c.sk) r3 ^= k[51] r2 ^= k[50] r1 ^= k[49] r0 ^= k[48] f(&r0, &r1, &r2, &r3, k[46], k[47]) f(&r2, &r3, &r0, &r1, k[44], k[45]) f(&r0, &r1, &r2, &r3, k[42], k[43]) f(&r2, &r3, &r0, &r1, k[40], k[41]) f(&r0, &r1, &r2, &r3, k[38], k[39]) f(&r2, &r3, &r0, &r1, k[36], k[37]) t := r0 & k[34] r1 ^= (t << 1) | (t >> (32 - 1)) r2 ^= r3 | k[33] r0 ^= r1 | k[35] t = r2 & k[32] r3 ^= (t << 1) | (t >> (32 - 1)) f(&r0, &r1, &r2, &r3, k[30], k[31]) f(&r2, &r3, &r0, &r1, k[28], k[29]) f(&r0, &r1, &r2, &r3, k[26], k[27]) f(&r2, &r3, &r0, &r1, k[24], k[25]) f(&r0, &r1, &r2, &r3, k[22], k[23]) f(&r2, &r3, &r0, &r1, k[20], k[21]) t = r0 & k[18] r1 ^= (t << 1) | (t >> (32 - 1)) r2 ^= r3 | k[17] r0 ^= r1 | k[19] t = r2 & k[16] r3 ^= (t << 1) | (t >> (32 - 1)) f(&r0, &r1, &r2, &r3, k[14], k[15]) f(&r2, &r3, &r0, &r1, k[12], k[13]) f(&r0, &r1, &r2, &r3, k[10], k[11]) f(&r2, &r3, &r0, &r1, k[8], k[9]) f(&r0, &r1, &r2, &r3, k[6], k[7]) f(&r2, &r3, &r0, &r1, k[4], k[5]) r1 ^= k[3] r0 ^= k[2] r3 ^= k[1] r2 ^= k[0] dst[0] = byte(r2 >> 24) dst[1] = byte(r2 >> 16) dst[2] = byte(r2 >> 8) dst[3] = byte(r2) dst[4] = byte(r3 >> 24) dst[5] = byte(r3 >> 16) dst[6] = byte(r3 >> 8) dst[7] = byte(r3) dst[8] = byte(r0 >> 24) dst[9] = byte(r0 >> 16) dst[10] = byte(r0 >> 8) dst[11] = byte(r0) dst[12] = byte(r1 >> 24) dst[13] = byte(r1 >> 16) dst[14] = byte(r1 >> 8) dst[15] = byte(r1) } // The camellia cipher for 192 or 256 bit keys. type blockCipher256 struct { sk [68]uint32 // The 68 32-bit subkeys } func (c *blockCipher256) BlockSize() int { return BlockSize } func (c *blockCipher256) Encrypt(dst, src []byte) { if len(src) < BlockSize { panic("camellia: src buffer to small") } if len(dst) < BlockSize { panic("camellia: dst buffer to small") } r0 := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3]) r1 := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7]) r2 := uint32(src[8])<<24 | uint32(src[9])<<16 | uint32(src[10])<<8 | uint32(src[11]) r3 := uint32(src[12])<<24 | uint32(src[13])<<16 | uint32(src[14])<<8 | uint32(src[15]) k := &(c.sk) r0 ^= k[0] r1 ^= k[1] r2 ^= k[2] r3 ^= k[3] f(&r0, &r1, &r2, &r3, k[4], k[5]) f(&r2, &r3, &r0, &r1, k[6], k[7]) f(&r0, &r1, &r2, &r3, k[8], k[9]) f(&r2, &r3, &r0, &r1, k[10], k[11]) f(&r0, &r1, &r2, &r3, k[12], k[13]) f(&r2, &r3, &r0, &r1, k[14], k[15]) t := r0 & k[16] r1 ^= (t << 1) | (t >> (32 - 1)) r2 ^= r3 | k[19] r0 ^= r1 | k[17] t = r2 & k[18] r3 ^= (t << 1) | (t >> (32 - 1)) f(&r0, &r1, &r2, &r3, k[20], k[21]) f(&r2, &r3, &r0, &r1, k[22], k[23]) f(&r0, &r1, &r2, &r3, k[24], k[25]) f(&r2, &r3, &r0, &r1, k[26], k[27]) f(&r0, &r1, &r2, &r3, k[28], k[29]) f(&r2, &r3, &r0, &r1, k[30], k[31]) t = r0 & k[32] r1 ^= (t << 1) | (t >> (32 - 1)) r2 ^= r3 | k[35] r0 ^= r1 | k[33] t = r2 & k[34] r3 ^= (t << 1) | (t >> (32 - 1)) f(&r0, &r1, &r2, &r3, k[36], k[37]) f(&r2, &r3, &r0, &r1, k[38], k[39]) f(&r0, &r1, &r2, &r3, k[40], k[41]) f(&r2, &r3, &r0, &r1, k[42], k[43]) f(&r0, &r1, &r2, &r3, k[44], k[45]) f(&r2, &r3, &r0, &r1, k[46], k[47]) t = r0 & k[48] r1 ^= (t << 1) | (t >> (32 - 1)) r2 ^= r3 | k[51] r0 ^= r1 | k[49] t = r2 & k[50] r3 ^= (t << 1) | (t >> (32 - 1)) f(&r0, &r1, &r2, &r3, k[52], k[53]) f(&r2, &r3, &r0, &r1, k[54], k[55]) f(&r0, &r1, &r2, &r3, k[56], k[57]) f(&r2, &r3, &r0, &r1, k[58], k[59]) f(&r0, &r1, &r2, &r3, k[60], k[61]) f(&r2, &r3, &r0, &r1, k[62], k[63]) r2 ^= c.sk[64] r3 ^= c.sk[65] r0 ^= c.sk[66] r1 ^= c.sk[67] dst[0] = byte(r2 >> 24) dst[1] = byte(r2 >> 16) dst[2] = byte(r2 >> 8) dst[3] = byte(r2) dst[4] = byte(r3 >> 24) dst[5] = byte(r3 >> 16) dst[6] = byte(r3 >> 8) dst[7] = byte(r3) dst[8] = byte(r0 >> 24) dst[9] = byte(r0 >> 16) dst[10] = byte(r0 >> 8) dst[11] = byte(r0) dst[12] = byte(r1 >> 24) dst[13] = byte(r1 >> 16) dst[14] = byte(r1 >> 8) dst[15] = byte(r1) } func (c *blockCipher256) Decrypt(dst, src []byte) { if len(src) < BlockSize { panic("camellia: src buffer to small") } if len(dst) < BlockSize { panic("camellia: dst buffer to small") } r0 := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3]) r1 := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7]) r2 := uint32(src[8])<<24 | uint32(src[9])<<16 | uint32(src[10])<<8 | uint32(src[11]) r3 := uint32(src[12])<<24 | uint32(src[13])<<16 | uint32(src[14])<<8 | uint32(src[15]) k := &(c.sk) r3 ^= k[67] r2 ^= k[66] r1 ^= k[65] r0 ^= k[64] f(&r0, &r1, &r2, &r3, k[62], k[63]) f(&r2, &r3, &r0, &r1, k[60], k[61]) f(&r0, &r1, &r2, &r3, k[58], k[59]) f(&r2, &r3, &r0, &r1, k[56], k[57]) f(&r0, &r1, &r2, &r3, k[54], k[55]) f(&r2, &r3, &r0, &r1, k[52], k[53]) t := r0 & k[50] r1 ^= (t << 1) | (t >> (32 - 1)) r2 ^= r3 | k[49] r0 ^= r1 | k[51] t = r2 & k[48] r3 ^= (t << 1) | (t >> (32 - 1)) f(&r0, &r1, &r2, &r3, k[46], k[47]) f(&r2, &r3, &r0, &r1, k[44], k[45]) f(&r0, &r1, &r2, &r3, k[42], k[43]) f(&r2, &r3, &r0, &r1, k[40], k[41]) f(&r0, &r1, &r2, &r3, k[38], k[39]) f(&r2, &r3, &r0, &r1, k[36], k[37]) t = r0 & k[34] r1 ^= (t << 1) | (t >> (32 - 1)) r2 ^= r3 | k[33] r0 ^= r1 | k[35] t = r2 & k[32] r3 ^= (t << 1) | (t >> (32 - 1)) f(&r0, &r1, &r2, &r3, k[30], k[31]) f(&r2, &r3, &r0, &r1, k[28], k[29]) f(&r0, &r1, &r2, &r3, k[26], k[27]) f(&r2, &r3, &r0, &r1, k[24], k[25]) f(&r0, &r1, &r2, &r3, k[22], k[23]) f(&r2, &r3, &r0, &r1, k[20], k[21]) t = r0 & k[18] r1 ^= (t << 1) | (t >> (32 - 1)) r2 ^= r3 | k[17] r0 ^= r1 | k[19] t = r2 & k[16] r3 ^= (t << 1) | (t >> (32 - 1)) f(&r0, &r1, &r2, &r3, k[14], k[15]) f(&r2, &r3, &r0, &r1, k[12], k[13]) f(&r0, &r1, &r2, &r3, k[10], k[11]) f(&r2, &r3, &r0, &r1, k[8], k[9]) f(&r0, &r1, &r2, &r3, k[6], k[7]) f(&r2, &r3, &r0, &r1, k[4], k[5]) r1 ^= k[3] r0 ^= k[2] r3 ^= k[1] r2 ^= k[0] dst[0] = byte(r2 >> 24) dst[1] = byte(r2 >> 16) dst[2] = byte(r2 >> 8) dst[3] = byte(r2) dst[4] = byte(r3 >> 24) dst[5] = byte(r3 >> 16) dst[6] = byte(r3 >> 8) dst[7] = byte(r3) dst[8] = byte(r0 >> 24) dst[9] = byte(r0 >> 16) dst[10] = byte(r0 >> 8) dst[11] = byte(r0) dst[12] = byte(r1 >> 24) dst[13] = byte(r1 >> 16) dst[14] = byte(r1 >> 8) dst[15] = byte(r1) } // The camellia key schedule for 128 bit keys. func (c *blockCipher128) keySchedule(key []byte) { r0 := uint32(key[0])<<24 | uint32(key[1])<<16 | uint32(key[2])<<8 | uint32(key[3]) r1 := uint32(key[4])<<24 | uint32(key[5])<<16 | uint32(key[6])<<8 | uint32(key[7]) r2 := uint32(key[8])<<24 | uint32(key[9])<<16 | uint32(key[10])<<8 | uint32(key[11]) r3 := uint32(key[12])<<24 | uint32(key[13])<<16 | uint32(key[14])<<8 | uint32(key[15]) k := &(c.sk) k[0], k[1], k[2], k[3] = r0, r1, r2, r3 f(&r0, &r1, &r2, &r3, sigma[0], sigma[1]) f(&r2, &r3, &r0, &r1, sigma[2], sigma[3]) r0 ^= k[0] r1 ^= k[1] r2 ^= k[2] r3 ^= k[3] f(&r0, &r1, &r2, &r3, sigma[4], sigma[5]) f(&r2, &r3, &r0, &r1, sigma[6], sigma[7]) k[4], k[5], k[6], k[7] = r0, r1, r2, r3 rotl128(&r0, &r1, &r2, &r3, 15) // KA <<< 15 k[12], k[13], k[14], k[15] = r0, r1, r2, r3 rotl128(&r0, &r1, &r2, &r3, 15) // KA <<< 30 k[16], k[17], k[18], k[19] = r0, r1, r2, r3 rotl128(&r0, &r1, &r2, &r3, 15) // KA <<< 45 k[24] = r0 k[25] = r1 rotl128(&r0, &r1, &r2, &r3, 15) // KA <<< 60 k[28], k[29], k[30], k[31] = r0, r1, r2, r3 rotl128(&r1, &r2, &r3, &r0, 2) // KA <<< 94 k[40], k[41], k[42], k[43] = r1, r2, r3, r0 rotl128(&r1, &r2, &r3, &r0, 17) // KA <<<111 k[48], k[49], k[50], k[51] = r1, r2, r3, r0 r0, r1, r2, r3 = k[0], k[1], k[2], k[3] rotl128(&r0, &r1, &r2, &r3, 15) // KL <<< 15 k[8], k[9], k[10], k[11] = r0, r1, r2, r3 rotl128(&r0, &r1, &r2, &r3, 30) // KL <<< 45 k[20], k[21], k[22], k[23] = r0, r1, r2, r3 rotl128(&r0, &r1, &r2, &r3, 15) // KL <<< 60 k[26] = r2 k[27] = r3 rotl128(&r0, &r1, &r2, &r3, 17) // KL <<< 77 k[32], k[33], k[34], k[35] = r0, r1, r2, r3 rotl128(&r0, &r1, &r2, &r3, 17) // KL <<< 94 k[36], k[37], k[38], k[39] = r0, r1, r2, r3 rotl128(&r0, &r1, &r2, &r3, 17) // KL <<<111 k[44], k[45], k[46], k[47] = r0, r1, r2, r3 } // The camellia key schedule for 192 or 256 bit keys. func (c *blockCipher256) keySchedule(key []byte) { k := &(c.sk) k[0] = uint32(key[0])<<24 | uint32(key[1])<<16 | uint32(key[2])<<8 | uint32(key[3]) k[1] = uint32(key[4])<<24 | uint32(key[5])<<16 | uint32(key[6])<<8 | uint32(key[7]) k[2] = uint32(key[8])<<24 | uint32(key[9])<<16 | uint32(key[10])<<8 | uint32(key[11]) k[3] = uint32(key[12])<<24 | uint32(key[13])<<16 | uint32(key[14])<<8 | uint32(key[15]) k[8] = uint32(key[16])<<24 | uint32(key[17])<<16 | uint32(key[18])<<8 | uint32(key[19]) k[9] = uint32(key[20])<<24 | uint32(key[21])<<16 | uint32(key[22])<<8 | uint32(key[23]) if len(key) == 24 { k[10] = ^k[8] k[11] = ^k[9] } else { k[10] = uint32(key[24])<<24 | uint32(key[25])<<16 | uint32(key[26])<<8 | uint32(key[27]) k[11] = uint32(key[28])<<24 | uint32(key[29])<<16 | uint32(key[30])<<8 | uint32(key[31]) } s0 := k[8] ^ k[0] s1 := k[9] ^ k[1] s2 := k[10] ^ k[2] s3 := k[11] ^ k[3] f(&s0, &s1, &s2, &s3, sigma[0], sigma[1]) f(&s2, &s3, &s0, &s1, sigma[2], sigma[3]) s0 ^= k[0] s1 ^= k[1] s2 ^= k[2] s3 ^= k[3] f(&s0, &s1, &s2, &s3, sigma[4], sigma[5]) f(&s2, &s3, &s0, &s1, sigma[6], sigma[7]) k[12], k[13], k[14], k[15] = s0, s1, s2, s3 s0 ^= k[8] s1 ^= k[9] s2 ^= k[10] s3 ^= k[11] f(&s0, &s1, &s2, &s3, sigma[8], sigma[9]) f(&s2, &s3, &s0, &s1, sigma[10], sigma[11]) k[4], k[5], k[6], k[7] = s0, s1, s2, s3 rotl128(&s0, &s1, &s2, &s3, 30) // KB <<< 30 k[20], k[21], k[22], k[23] = s0, s1, s2, s3 rotl128(&s0, &s1, &s2, &s3, 30) // KB <<< 60 k[40], k[41], k[42], k[43] = s0, s1, s2, s3 rotl128(&s1, &s2, &s3, &s0, 19) // KB <<<111 k[64], k[65], k[66], k[67] = s1, s2, s3, s0 s0, s1, s2, s3 = k[8], k[9], k[10], k[11] rotl128(&s0, &s1, &s2, &s3, 15) // KR <<< 15 k[8], k[9], k[10], k[11] = s0, s1, s2, s3 rotl128(&s0, &s1, &s2, &s3, 15) // KR <<< 30 k[16], k[17], k[18], k[19] = s0, s1, s2, s3 rotl128(&s0, &s1, &s2, &s3, 30) // KR <<< 60 k[36], k[37], k[38], k[39] = s0, s1, s2, s3 rotl128(&s1, &s2, &s3, &s0, 2) // KR <<< 94 k[52], k[53], k[54], k[55] = s1, s2, s3, s0 s0, s1, s2, s3 = k[12], k[13], k[14], k[15] rotl128(&s0, &s1, &s2, &s3, 15) // KA <<< 15 k[12], k[13], k[14], k[15] = s0, s1, s2, s3 rotl128(&s0, &s1, &s2, &s3, 30) // KA <<< 45 k[28], k[29], k[30], k[31] = s0, s1, s2, s3 // KA <<< 77 k[48], k[49], k[50], k[51] = s1, s2, s3, s0 rotl128(&s1, &s2, &s3, &s0, 17) // KA <<< 94 k[56], k[57], k[58], k[59] = s1, s2, s3, s0 s0, s1, s2, s3 = k[0], k[1], k[2], k[3] rotl128(&s1, &s2, &s3, &s0, 13) // KL <<< 45 k[24], k[25], k[26], k[27] = s1, s2, s3, s0 rotl128(&s1, &s2, &s3, &s0, 15) // KL <<< 60 k[32], k[33], k[34], k[35] = s1, s2, s3, s0 rotl128(&s1, &s2, &s3, &s0, 17) // KL <<< 77 k[44], k[45], k[46], k[47] = s1, s2, s3, s0 rotl128(&s2, &s3, &s0, &s1, 2) // KL <<<111 k[60], k[61], k[62], k[63] = s2, s3, s0, s1 } golang-github-enceve-crypto-0.0~git20160707.34d48bb/camellia/camellia_ref.go000066400000000000000000000016531520706056300261750ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package camellia // The camellia non-linear feistel function. func f(r0, r1, r2, r3 *uint32, k0, k1 uint32) { k0 ^= *r0 k1 ^= *r1 t := sbox4_4404[byte(k0)] t ^= sbox3_3033[byte(k0>>8)] t ^= sbox2_0222[byte(k0>>16)] t ^= sbox1_1110[byte(k0>>24)] *r3 ^= (t >> 8) | (t << (32 - 8)) k0 = t k0 ^= sbox1_1110[byte(k1)] k0 ^= sbox4_4404[byte(k1>>8)] k0 ^= sbox3_3033[byte(k1>>16)] k0 ^= sbox2_0222[byte(k1>>24)] *r2 ^= k0 *r3 ^= k0 } // Note that n has to be less than 32. Rotations for larger amount // of bits are achieved by "rotating" order of registers and // adjusting n accordingly, e.g. RotLeft128(r1,r2,r3,r0,n-32). func rotl128(r0, r1, r2, r3 *uint32, n uint) { t := *r0 >> (32 - n) *r0 = (*r0 << n) | (*r1 >> (32 - n)) *r1 = (*r1 << n) | (*r2 >> (32 - n)) *r2 = (*r2 << n) | (*r3 >> (32 - n)) *r3 = (*r3 << n) | t } golang-github-enceve-crypto-0.0~git20160707.34d48bb/camellia/camellia_test.go000066400000000000000000000102671520706056300264010ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package camellia import ( "bytes" "crypto/cipher" "encoding/hex" "testing" ) var recoverFail = func(t *testing.T) { if err := recover(); err == nil { t.Fatal("Recover expected error, but no one occured") } } var badKeys = [][]byte{ make([]byte, 15), make([]byte, 17), make([]byte, 23), make([]byte, 25), make([]byte, 31), make([]byte, 33), } func TestBlockSize(t *testing.T) { c, err := NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Failed to create camellia cipher: %s", err) } if bs := c.BlockSize(); bs != BlockSize { t.Fatalf("BlockSize() returned unexpected value: %d", bs) } c, err = NewCipher(make([]byte, 32)) if err != nil { t.Fatalf("Failed to create camellia cipher: %s", err) } if bs := c.BlockSize(); bs != BlockSize { t.Fatalf("BlockSize() returned unexpected value: %d", bs) } } func TestEncrypt(t *testing.T) { encFail := func(t *testing.T, c cipher.Block, srcLen, dstLen int) { defer recoverFail(t) src := make([]byte, srcLen) dst := make([]byte, dstLen) c.Encrypt(dst, src) } c, err := NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Failed to create camellia cipher: %s", err) } encFail(t, c, BlockSize-1, BlockSize) encFail(t, c, BlockSize, BlockSize-1) c, err = NewCipher(make([]byte, 32)) if err != nil { t.Fatalf("Failed to create camellia cipher: %s", err) } encFail(t, c, BlockSize-1, BlockSize) encFail(t, c, BlockSize, BlockSize-1) } func TestDecrypt(t *testing.T) { decFail := func(t *testing.T, c cipher.Block, srcLen, dstLen int) { defer recoverFail(t) src := make([]byte, srcLen) dst := make([]byte, dstLen) c.Decrypt(dst, src) } c, err := NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Failed to create camellia cipher: %s", err) } decFail(t, c, BlockSize-1, BlockSize) decFail(t, c, BlockSize, BlockSize-1) c, err = NewCipher(make([]byte, 32)) if err != nil { t.Fatalf("Failed to create camellia cipher: %s", err) } decFail(t, c, BlockSize-1, BlockSize) decFail(t, c, BlockSize, BlockSize-1) } func TestEncryptDecrypt(t *testing.T) { c, err := NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Failed to create camellia cipher: %s", err) } src := make([]byte, 32) dst := make([]byte, 32) c.Encrypt(dst, src) c.Encrypt(dst[16:], src[:16]) c.Decrypt(dst, dst) c.Decrypt(dst[16:], dst[16:]) if !bytes.Equal(src, dst) { t.Fatalf("En / decryption sequence failed\nFound: %s\nExpected: %s", hex.EncodeToString(dst), hex.EncodeToString(src)) } } func TestNewCipher(t *testing.T) { var ( key128 [16]byte key192 [24]byte key256 [32]byte ) _, err := NewCipher(key128[:]) if err != nil { t.Fatalf("NewCipher rejected valid key with length: %d", len(key128)) } _, err = NewCipher(key192[:]) if err != nil { t.Fatalf("NewCipher rejected valid key with length: %d", len(key192)) } _, err = NewCipher(key256[:]) if err != nil { t.Fatalf("NewCipher rejected valid key with length: %d", len(key256)) } for i, v := range badKeys { _, err := NewCipher(v) if err == nil { t.Fatalf("NewCipher accpeted bad key %d with length: %d", i, len(v)) } } } // Benchmarks func BenchmarkEncrypt_16(b *testing.B) { benchmarkEncrypt(b, 16) } func BenchmarkDecrypt_16(b *testing.B) { benchmarkDecrypt(b, 16) } func BenchmarkEncrypt_1K(b *testing.B) { benchmarkEncrypt(b, 1024) } func BenchmarkDecrypt_1K(b *testing.B) { benchmarkDecrypt(b, 1024) } func benchmarkEncrypt(b *testing.B, size int) { c, err := NewCipher(make([]byte, 16)) if err != nil { b.Fatalf("Failed to create camellia instance: %s", err) } buf := make([]byte, c.BlockSize()) b.SetBytes(int64(size - (size % c.BlockSize()))) n := size / c.BlockSize() b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < n; j++ { c.Encrypt(buf, buf) } } } func benchmarkDecrypt(b *testing.B, size int) { c, err := NewCipher(make([]byte, 16)) if err != nil { b.Fatalf("Failed to create camelli instance: %s", err) } buf := make([]byte, c.BlockSize()) b.SetBytes(int64(size - (size % c.BlockSize()))) n := size / c.BlockSize() b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < n; j++ { c.Decrypt(buf, buf) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/camellia/sbox.go000066400000000000000000000313311520706056300245410ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package camellia // The camellia sigma constants var sigma = []uint32{ 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd, } // The first camellia sbox var sbox1_1110 = [256]uint32{ 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00, } // The second camellia sbox var sbox2_0222 = [256]uint32{ 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d, } // The third camellia sbox var sbox3_3033 = [256]uint32{ 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f, } // The fourth camellia sbox var sbox4_4404 = [256]uint32{ 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e, } golang-github-enceve-crypto-0.0~git20160707.34d48bb/camellia/vectors_test.go000066400000000000000000000032671520706056300263210ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package camellia import ( "bytes" "encoding/hex" "testing" ) type testVector struct { key, plaintext, ciphertext string } func fromHex(s string) []byte { b, err := hex.DecodeString(s) if err != nil { panic(err) } return b } // Test vectors from RFC3713 - https://www.ietf.org/rfc/rfc3713.txt var vectors = []struct { key, plaintext, ciphertext string }{ { key: "0123456789abcdeffedcba9876543210", plaintext: "0123456789abcdeffedcba9876543210", ciphertext: "67673138549669730857065648eabe43", }, { key: "0123456789abcdeffedcba98765432100011223344556677", plaintext: "0123456789abcdeffedcba9876543210", ciphertext: "b4993401b3e996f84ee5cee7d79b09b9", }, { key: "0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff", plaintext: "0123456789abcdeffedcba9876543210", ciphertext: "9acc237dff16d76c20ef7c919e3a7509", }, } func TestVectors(t *testing.T) { for i, v := range vectors { key := fromHex(v.key) plaintext := fromHex(v.plaintext) ciphertext := fromHex(v.ciphertext) buf := make([]byte, BlockSize) c, err := NewCipher(key) if err != nil { t.Fatalf("Test vector %d: Failed to create Camellia instance: %s", i, err) } c.Encrypt(buf, plaintext) if !bytes.Equal(ciphertext, buf) { t.Fatalf("Test vector %d:\nEncryption failed\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(ciphertext)) } c.Decrypt(buf, buf) if !bytes.Equal(plaintext, buf) { t.Fatalf("Test vector %d:\nDecryption failed\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(plaintext)) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/000077500000000000000000000000001520706056300230405ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/chacha/000077500000000000000000000000001520706056300242475ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/chacha/chacha.go000066400000000000000000000014361520706056300260110ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package chacha implements some low level functions of the // ChaCha cipher family. package chacha var constants = [16]byte{ 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x20, 0x33, 0x32, 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 0x6b, } // Cipher is the ChaCha/X struct. // X is the number of rounds (e.g. ChaCha20 for 20 rounds) type Cipher struct { state, block [64]byte off int rounds int } // Sets the counter of the cipher. // Notice that this function skips the unused // keystream of the current 64 byte block. func (c *Cipher) SetCounter(ctr uint32) { c.state[48] = byte(ctr) c.state[49] = byte(ctr >> 8) c.state[50] = byte(ctr >> 16) c.state[51] = byte(ctr >> 24) c.off = 0 } golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/chacha/chacha_amd64.go000066400000000000000000000066001520706056300270020ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build amd64,!gccgo,!appengine package chacha import ( "unsafe" "github.com/enceve/crypto" ) // XORKeyStream crypts bytes from src to dst using the given key, nonce and counter. // The rounds argument specifies the number of rounds (must be even) performed for // keystream generation. (Common values are 20, 12 or 8) Src and dst may be the same // slice but otherwise should not overlap. If len(dst) < len(src) this function panics. func XORKeyStream(dst, src []byte, nonce *[12]byte, key *[32]byte, counter uint32, rounds int) { length := len(src) if len(dst) < length { panic("chacha20/chacha: dst buffer is to small") } if rounds <= 0 || rounds%2 != 0 { panic("chacha20/chacha: rounds must be a multiple of 2") } var state [64]byte copy(state[:], constants[:]) statePtr := (*[8]uint64)(unsafe.Pointer(&state[0])) keyPtr := (*[4]uint64)(unsafe.Pointer(&key[0])) statePtr[2] = keyPtr[0] statePtr[3] = keyPtr[1] statePtr[4] = keyPtr[2] statePtr[5] = keyPtr[3] statePtr[6] = (*(*uint64)(unsafe.Pointer(&nonce[0])) << 32) | uint64(counter) statePtr[7] = *(*uint64)(unsafe.Pointer(&nonce[4])) if length >= 64 { XORBlocks(dst, src, &state, rounds) } if n := length & (^(64 - 1)); length-n > 0 { var block [64]byte Core(&block, &state, rounds) crypto.XOR(dst[n:], src[n:], block[:]) } } // NewCipher returns a new *chacha.Cipher implementing the ChaCha/X (X = even number of rounds) // stream cipher. The nonce must be unique for one key for all time. func NewCipher(nonce *[12]byte, key *[32]byte, rounds int) *Cipher { if rounds <= 0 || rounds%2 != 0 { panic("chacha20/chacha: rounds must be a multiply of 2") } c := new(Cipher) c.rounds = rounds copy(c.state[:], constants[:]) statePtr := (*[8]uint64)(unsafe.Pointer(&(c.state[0]))) keyPtr := (*[4]uint64)(unsafe.Pointer(&key[0])) statePtr[2] = keyPtr[0] statePtr[3] = keyPtr[1] statePtr[4] = keyPtr[2] statePtr[5] = keyPtr[3] statePtr[6] = (*(*uint64)(unsafe.Pointer(&nonce[0])) << 32) statePtr[7] = *(*uint64)(unsafe.Pointer(&nonce[4])) return c } // XORKeyStream crypts bytes from src to dst. Src and dst may be the same slice // but otherwise should not overlap. If len(dst) < len(src) the function panics. func (c *Cipher) XORKeyStream(dst, src []byte) { length := len(src) if len(dst) < length { panic("chacha20/chacha: dst buffer is to small") } if c.off > 0 { n := crypto.XOR(dst, src, c.block[c.off:]) if n == length { c.off += n return } src = src[n:] dst = dst[n:] length -= n c.off = 0 } if length >= 64 { XORBlocks(dst, src, &(c.state), c.rounds) } if n := length & (^(64 - 1)); length-n > 0 { Core(&(c.block), &(c.state), c.rounds) c.off += crypto.XOR(dst[n:], src[n:], c.block[:]) } } // XORBlocks crypts full block ( len(src) - (len(src) mod 64) bytes ) from src to // dst using the state. Src and dst may be the same slice but otherwise should not // overlap. This function increments the counter of state. // If len(src) > len(dst), XORBlocks does nothing. func XORBlocks(dst, src []byte, state *[64]byte, rounds int) // Core generates 64 byte keystream from the given state performing 'rounds' rounds // and writes them to dst. This function expects valid values. (no nil ptr etc.) // Core increments the counter of state. func Core(dst *[64]byte, state *[64]byte, rounds int) golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/chacha/chacha_amd64.s000066400000000000000000000160351520706056300266420ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. #define ROTL32(n, v , t) \ MOVO v, t; \ PSLLL $n, t; \ PSRLL $(32-n), v; \ PXOR t, v #define HALF_ROUND_64B(v0 , v1 , v2 , v3 , t0) \ PADDL v1, v0; \ PXOR v0, v3; \ ROTL32(16, v3, t0); \ PADDL v3, v2; \ PXOR v2, v1; \ ROTL32(12, v1, t0); \ PADDL v1, v0; \ PXOR v0, v3; \ ROTL32(8, v3, t0); \ PADDL v3, v2; \ PXOR v2, v1; \ ROTL32(7, v1, t0); \ #define ROUND_64B(v0 , v1 , v2 , v3 , t0) \ HALF_ROUND_64B(v0, v1, v2, v3, t0); \ PSHUFL $57, v1, v1; \ PSHUFL $78, v2, v2; \ PSHUFL $147, v3, v3; \ HALF_ROUND_64B(v0, v1, v2, v3, t0); \ PSHUFL $147, v1, v1; \ PSHUFL $78, v2, v2; \ PSHUFL $57, v3, v3 #define HALF_ROUND_128B(v0, v1, v2, v3, v4, v5, v6, v7, t0) \ PADDL v1, v0; \ PADDL v5, v4; \ PXOR v0, v3; \ PXOR v4, v7; \ ROTL32(16, v3, t0); \ ROTL32(16, v7, t0); \ PADDL v3, v2; \ PADDL v7, v6; \ PXOR v2, v1; \ PXOR v6, v5; \ ROTL32(12, v1, t0); \ ROTL32(12, v5, t0); \ PADDL v1, v0; \ PADDL v5, v4; \ PXOR v0, v3; \ PXOR v4, v7; \ ROTL32(8, v3, t0); \ ROTL32(8, v7, t0); \ PADDL v3, v2; \ PADDL v7, v6; \ PXOR v2, v1; \ PXOR v6, v5; \ ROTL32(7, v1, t0); \ ROTL32(7, v5, t0); \ #define ROUND_128B(v0, v1, v2, v3, v4, v5, v6, v7, t0) \ HALF_ROUND_128B(v0, v1, v2, v3, v4, v5, v6, v7, t0); \ PSHUFL $57, v1, v1; \ PSHUFL $57, v5, v5; \ PSHUFL $78, v2, v2; \ PSHUFL $78, v6, v6; \ PSHUFL $147, v3, v3; \ PSHUFL $147, v7, v7; \ HALF_ROUND_128B(v0, v1, v2, v3, v4, v5, v6, v7, t0); \ PSHUFL $147, v1, v1; \ PSHUFL $147, v5, v5; \ PSHUFL $78, v2, v2; \ PSHUFL $78, v6, v6; \ PSHUFL $57, v3, v3; \ PSHUFL $57, v7, v7 #define HALF_ROUND_256B(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, t0) \ PADDL v1, v0; \ PADDL v5, v4; \ PADDL v9, v8; \ PADDL v13, v12; \ PXOR v0, v3; \ PXOR v4, v7; \ PXOR v8, v11; \ PXOR v12, v15; \ MOVO v12, t0; \ ROTL32(16, v3, v12); \ ROTL32(16, v7, v12); \ ROTL32(16, v11, v12); \ ROTL32(16, v15, v12); \ PADDL v3, v2; \ PADDL v7, v6; \ PADDL v11, v10; \ PADDL v15, v14; \ PXOR v2, v1; \ PXOR v6, v5; \ PXOR v10, v9; \ PXOR v14, v13; \ ROTL32(12, v1, v12); \ ROTL32(12, v5, v12); \ ROTL32(12, v9, v12); \ ROTL32(12, v13, v12); \ MOVO t0, v12; \ PADDL v1, v0; \ PADDL v5, v4; \ PADDL v9, v8; \ PADDL v13, v12; \ PXOR v0, v3; \ PXOR v4, v7; \ PXOR v8, v11; \ PXOR v12, v15; \ MOVO v12, 16(SP); \ ROTL32(8, v3, v12); \ ROTL32(8, v7, v12); \ ROTL32(8, v11, v12); \ ROTL32(8, v15, v12); \ PADDL v3, v2; \ PADDL v7, v6; \ PADDL v11, v10; \ PADDL v15, v14; \ PXOR v2, v1; \ PXOR v6, v5; \ PXOR v10, v9; \ PXOR v14, v13; \ ROTL32(7, v1, v12); \ ROTL32(7, v5, v12); \ ROTL32(7, v9, v12); \ ROTL32(7, v13, v12); \ #define ROUND_256B(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, t0) \ HALF_ROUND_256B(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, t0); \ PSHUFL $57, v1, v1; \ PSHUFL $57, v5, v5; \ PSHUFL $57, v9, v9; \ PSHUFL $57, v13, v13; \ PSHUFL $78, v2, v2; \ PSHUFL $78, v6, v6; \ PSHUFL $78, v10, v10; \ PSHUFL $78, v14, v14; \ PSHUFL $147, v3, v3; \ PSHUFL $147, v7, v7; \ PSHUFL $147, v11, v11; \ PSHUFL $147, v15, v15; \ MOVO t0, v12; \ HALF_ROUND_256B(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, t0); \ PSHUFL $147, v1, v1; \ PSHUFL $147, v5, v5; \ PSHUFL $147, v9, v9; \ PSHUFL $147, v13, v13; \ PSHUFL $78, v2, v2; \ PSHUFL $78, v6, v6; \ PSHUFL $78, v10, v10; \ PSHUFL $78, v14, v14; \ PSHUFL $57, v3, v3; \ PSHUFL $57, v7, v7; \ PSHUFL $57, v11, v11; \ PSHUFL $57, v15, v15; \ MOVO t0, v12 #define XOR_64B(dst, src, off, v0 , v1 , v2 , v3 , t0) \ MOVOU 0+off(src), t0; \ PXOR v0, t0; \ MOVOU t0, 0+off(dst); \ MOVOU 16+off(src), t0; \ PXOR v1, t0; \ MOVOU t0, 16+off(dst); \ MOVOU 32+off(src), t0; \ PXOR v2, t0; \ MOVOU t0, 32+off(dst); \ MOVOU 48+off(src), t0; \ PXOR v3, t0; \ MOVOU t0, 48+off(dst) // func Core(dst *[64]byte, state *[16]uint32, rounds int) TEXT ·Core(SB),4,$0-24 MOVQ state+8(FP), AX MOVQ dst+0(FP), BX MOVQ rounds+16(FP), CX MOVL 48(AX), DI MOVO 0(AX), X0 MOVO 16(AX), X1 MOVO 32(AX), X2 MOVO 48(AX), X3 MOVO X0, X4 MOVO X1, X5 MOVO X2, X6 MOVO X3, X7 loop: ROUND_64B(X4, X5, X6, X7, X8) SUBQ $2, CX JA loop PADDL X4, X0 PADDL X5, X1 PADDL X6, X2 PADDL X7, X3 MOVO X0, 0(BX) MOVO X1, 16(BX) MOVO X2, 32(BX) MOVO X3, 48(BX) ADDL $1, DI MOVL DI, 48(AX) RET TEXT ·XORBlocks(SB),4,$0-64 MOVQ state+48(FP), AX MOVQ dst+0(FP), BX MOVQ src+24(FP), CX MOVQ src+32(FP), DX MOVQ rounds+56(FP), DI CMPQ dst+8(FP), DX JB DONE MOVQ SP, SI MOVQ $31, BP NOTQ BP ANDQ BP, SP SUBQ $32, SP PXOR X0, X0 SUBQ $32, SP MOVO X0, 0(SP) MOVL $1, BP MOVL BP, 0(SP) CMPQ DX, $256 JB BYTES_BETWEEN_0_AND_255 BYTES_AT_LEAST_256: MOVO 0(AX), X0 MOVO 16(AX), X1 MOVO 32(AX), X2 MOVO 48(AX), X3 MOVO X0, X4 MOVO X1, X5 MOVO X2, X6 MOVO X3, X7 PADDQ 0(SP), X7 MOVO X0, X8 MOVO X1, X9 MOVO X2, X10 MOVO X7, X11 PADDQ 0(SP), X11 MOVO X0, X12 MOVO X1, X13 MOVO X2, X14 MOVO X11, X15 PADDQ 0(SP), X15 MOVQ DI, BP CHACHA_LOOP_256: ROUND_256B(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, 16(SP)) SUBQ $2, BP JA CHACHA_LOOP_256 MOVO X12, 16(SP) PADDL 0(AX), X0 PADDL 16(AX), X1 PADDL 32(AX), X2 PADDL 48(AX), X3 XOR_64B(BX, CX, 0, X0, X1, X2, X3, X12) MOVO 48(AX), X3 PADDQ 0(SP), X3 PADDL 0(AX), X4 PADDL 16(AX), X5 PADDL 32(AX), X6 PADDL X3, X7 XOR_64B(BX, CX, 64, X4, X5, X6, X7, X12) PADDQ 0(SP), X3 PADDL 0(AX), X8 PADDL 16(AX), X9 PADDL 32(AX), X10 PADDL X3, X11 XOR_64B(BX, CX, 128, X8, X9, X10, X11, X12) PADDQ 0(SP), X3 MOVO 16(SP), X12 PADDL 0(AX), X12 PADDL 16(AX), X13 PADDL 32(AX), X14 PADDL X3, X15 XOR_64B(BX, CX, 192, X12, X13, X14, X15, X0) PADDQ 0(SP), X3 MOVO X3, 48(AX) ADDQ $256, CX ADDQ $256, BX SUBQ $256, DX CMPQ DX, $256 JAE BYTES_AT_LEAST_256 BYTES_BETWEEN_0_AND_255: CMPQ DX, $0 JE DONE CMPQ DX, $128 JB BYTES_BETWEEN_0_AND_127 MOVQ 0(SP), X15 MOVO 0(AX), X0 MOVO 16(AX), X1 MOVO 32(AX), X2 MOVO 48(AX), X3 MOVO X0, X4 MOVO X1, X5 MOVO X2, X6 MOVO X3, X7 MOVO X0, X8 MOVO X1, X9 MOVO X2, X10 MOVO X3, X11 PADDQ X15, X11 MOVQ DI, BP CHACHA_LOOP_128: ROUND_128B(X4, X5, X6, X7, X8, X9, X10, X11, X12) SUBQ $2, BP JA CHACHA_LOOP_128 PADDL X0, X4 PADDL X1, X5 PADDL X2, X6 PADDL X3, X7 XOR_64B(BX, CX, 0, X4, X5, X6, X7, X12) PADDQ X15, X3 PADDL X0, X8 PADDL X1, X9 PADDL X2, X10 PADDL X3, X11 XOR_64B(BX, CX, 64, X8, X9, X10, X11, X12) MOVO X3, 48(AX) ADDQ $128, CX ADDQ $128, BX SUBQ $128, DX BYTES_BETWEEN_0_AND_127: CMPQ DX, $64 JB DONE MOVQ 0(SP), X15 MOVO 0(AX), X0 MOVO 16(AX), X1 MOVO 32(AX), X2 MOVO 48(AX), X3 MOVO X0, X4 MOVO X1, X5 MOVO X2, X6 MOVO X3, X7 MOVQ DI, BP CHACHA_LOOP_64: ROUND_64B(X4, X5, X6, X7, X8) SUBQ $2, BP JA CHACHA_LOOP_64 PADDL X0, X4 PADDL X1, X5 PADDL X2, X6 PADDL X3, X7 XOR_64B(BX, CX, 0, X4, X5, X6, X7, X8) PADDQ X15, X3 MOVO X3, 48(AX) DONE: PXOR X0, X0 MOVO X0, 16(SP) MOVQ SI, SP RET golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/chacha/chacha_ref.go000066400000000000000000000213731520706056300266470ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build !amd64 package chacha import "github.com/enceve/crypto" // XORKeyStream crypts bytes from src to dst using the given key, nonce and counter. // The rounds argument specifies the number of rounds (must be even) performed for // keystream generation. (Common values are 20, 12 or 8) Src and dst may be the same // slice but otherwise should not overlap. If len(dst) < len(src) this function panics. func XORKeyStream(dst, src []byte, nonce *[12]byte, key *[32]byte, counter uint32, rounds int) { length := len(src) if len(dst) < length { panic("chacha20/chacha: dst buffer is to small") } if rounds <= 0 || rounds%2 != 0 { panic("chacha20/chacha: rounds must be a multiple of 2") } var state [64]byte copy(state[:], constants[:]) copy(state[16:], key[:]) state[48] = byte(counter) state[49] = byte(counter << 8) state[50] = byte(counter << 16) state[51] = byte(counter << 24) copy(state[52:], nonce[:]) if length >= 64 { XORBlocks(dst, src, &state, rounds) } if n := length & (^(64 - 1)); length-n > 0 { var block [64]byte Core(&block, &state, rounds) crypto.XOR(dst[n:], src[n:], block[:]) } } // NewCipher returns a new *chacha.Cipher implementing the ChaCha/X (X = even number of rounds) // stream cipher. The nonce must be unique for one key for all time. func NewCipher(nonce *[12]byte, key *[32]byte, rounds int) *Cipher { if rounds <= 0 || rounds%2 != 0 { panic("chacha20/chacha: rounds must be a multiply of 2") } c := new(Cipher) c.rounds = rounds copy(c.state[:], constants[:]) copy(c.state[16:], key[:]) copy(c.state[52:], nonce[:]) return c } // XORKeyStream crypts bytes from src to dst. Src and dst may be the same slice // but otherwise should not overlap. If len(dst) < len(src) the function panics. func (c *Cipher) XORKeyStream(dst, src []byte) { length := len(src) if len(dst) < length { panic("chacha20/chacha: dst buffer is to small") } if c.off > 0 { n := crypto.XOR(dst, src, c.block[c.off:]) if n == length { c.off += n return } src = src[n:] dst = dst[n:] length -= n c.off = 0 } if length >= 64 { XORBlocks(dst, src, &(c.state), c.rounds) } if n := length & (^(64 - 1)); length-n > 0 { Core(&(c.block), &(c.state), c.rounds) c.off += crypto.XOR(dst[n:], src[n:], c.block[:]) } } // XORBlocks crypts full block ( len(src) - (len(src) mod 64) bytes ) from src to // dst using the state. Src and dst may be the same slice // but otherwise should not overlap. If len(dst) < len(src) the behavior is undefined. // This function increments the counter of state. func XORBlocks(dst, src []byte, state *[64]byte, rounds int) { n := len(src) & (^(64 - 1)) var block [64]byte for i := 0; i < n; i += 64 { Core(&block, state, rounds) crypto.XOR(dst[i:], src[i:], block[:]) } } // Core generates 64 byte keystream from the given state performing 'rounds' rounds // and writes them to dst. This function expects valid values. (no nil ptr etc.) // Core increments the counter of the state. func Core(dst *[64]byte, state *[64]byte, rounds int) { v00 := uint32(state[0]) | (uint32(state[1]) << 8) | (uint32(state[2]) << 16) | (uint32(state[3]) << 24) v01 := uint32(state[4]) | (uint32(state[5]) << 8) | (uint32(state[6]) << 16) | (uint32(state[7]) << 24) v02 := uint32(state[8]) | (uint32(state[9]) << 8) | (uint32(state[10]) << 16) | (uint32(state[11]) << 24) v03 := uint32(state[12]) | (uint32(state[13]) << 8) | (uint32(state[14]) << 16) | (uint32(state[15]) << 24) v04 := uint32(state[16]) | (uint32(state[17]) << 8) | (uint32(state[18]) << 16) | (uint32(state[19]) << 24) v05 := uint32(state[20]) | (uint32(state[21]) << 8) | (uint32(state[22]) << 16) | (uint32(state[23]) << 24) v06 := uint32(state[24]) | (uint32(state[25]) << 8) | (uint32(state[26]) << 16) | (uint32(state[27]) << 24) v07 := uint32(state[28]) | (uint32(state[29]) << 8) | (uint32(state[30]) << 16) | (uint32(state[31]) << 24) v08 := uint32(state[32]) | (uint32(state[33]) << 8) | (uint32(state[34]) << 16) | (uint32(state[35]) << 24) v09 := uint32(state[36]) | (uint32(state[37]) << 8) | (uint32(state[38]) << 16) | (uint32(state[39]) << 24) v10 := uint32(state[40]) | (uint32(state[41]) << 8) | (uint32(state[42]) << 16) | (uint32(state[43]) << 24) v11 := uint32(state[44]) | (uint32(state[45]) << 8) | (uint32(state[46]) << 16) | (uint32(state[47]) << 24) v12 := uint32(state[48]) | (uint32(state[49]) << 8) | (uint32(state[50]) << 16) | (uint32(state[51]) << 24) v13 := uint32(state[52]) | (uint32(state[53]) << 8) | (uint32(state[54]) << 16) | (uint32(state[55]) << 24) v14 := uint32(state[56]) | (uint32(state[57]) << 8) | (uint32(state[58]) << 16) | (uint32(state[59]) << 24) v15 := uint32(state[60]) | (uint32(state[61]) << 8) | (uint32(state[62]) << 16) | (uint32(state[63]) << 24) s00, s01, s02, s03, s04, s05, s06, s07 := v00, v01, v02, v03, v04, v05, v06, v07 s08, s09, s10, s11, s12, s13, s14, s15 := v08, v09, v10, v11, v12, v13, v14, v15 for i := 0; i < rounds; i += 2 { v00 += v04 v12 ^= v00 v12 = (v12 << 16) | (v12 >> (16)) v08 += v12 v04 ^= v08 v04 = (v04 << 12) | (v04 >> (20)) v00 += v04 v12 ^= v00 v12 = (v12 << 8) | (v12 >> (24)) v08 += v12 v04 ^= v08 v04 = (v04 << 7) | (v04 >> (25)) v01 += v05 v13 ^= v01 v13 = (v13 << 16) | (v13 >> 16) v09 += v13 v05 ^= v09 v05 = (v05 << 12) | (v05 >> 20) v01 += v05 v13 ^= v01 v13 = (v13 << 8) | (v13 >> 24) v09 += v13 v05 ^= v09 v05 = (v05 << 7) | (v05 >> 25) v02 += v06 v14 ^= v02 v14 = (v14 << 16) | (v14 >> 16) v10 += v14 v06 ^= v10 v06 = (v06 << 12) | (v06 >> 20) v02 += v06 v14 ^= v02 v14 = (v14 << 8) | (v14 >> 24) v10 += v14 v06 ^= v10 v06 = (v06 << 7) | (v06 >> 25) v03 += v07 v15 ^= v03 v15 = (v15 << 16) | (v15 >> 16) v11 += v15 v07 ^= v11 v07 = (v07 << 12) | (v07 >> 20) v03 += v07 v15 ^= v03 v15 = (v15 << 8) | (v15 >> 24) v11 += v15 v07 ^= v11 v07 = (v07 << 7) | (v07 >> 25) v00 += v05 v15 ^= v00 v15 = (v15 << 16) | (v15 >> 16) v10 += v15 v05 ^= v10 v05 = (v05 << 12) | (v05 >> 20) v00 += v05 v15 ^= v00 v15 = (v15 << 8) | (v15 >> 24) v10 += v15 v05 ^= v10 v05 = (v05 << 7) | (v05 >> 25) v01 += v06 v12 ^= v01 v12 = (v12 << 16) | (v12 >> 16) v11 += v12 v06 ^= v11 v06 = (v06 << 12) | (v06 >> 20) v01 += v06 v12 ^= v01 v12 = (v12 << 8) | (v12 >> 24) v11 += v12 v06 ^= v11 v06 = (v06 << 7) | (v06 >> 25) v02 += v07 v13 ^= v02 v13 = (v13 << 16) | (v13 >> 16) v08 += v13 v07 ^= v08 v07 = (v07 << 12) | (v07 >> 20) v02 += v07 v13 ^= v02 v13 = (v13 << 8) | (v13 >> 24) v08 += v13 v07 ^= v08 v07 = (v07 << 7) | (v07 >> 25) v03 += v04 v14 ^= v03 v14 = (v14 << 16) | (v14 >> 16) v09 += v14 v04 ^= v09 v04 = (v04 << 12) | (v04 >> 20) v03 += v04 v14 ^= v03 v14 = (v14 << 8) | (v14 >> 24) v09 += v14 v04 ^= v09 v04 = (v04 << 7) | (v04 >> 25) } v00 += s00 v01 += s01 v02 += s02 v03 += s03 v04 += s04 v05 += s05 v06 += s06 v07 += s07 v08 += s08 v09 += s09 v10 += s10 v11 += s11 v12 += s12 v13 += s13 v14 += s14 v15 += s15 s12 += 1 state[48] = byte(s12) state[49] = byte(s12 >> 8) state[50] = byte(s12 >> 16) state[51] = byte(s12 >> 24) dst[0] = byte(v00) dst[1] = byte(v00 >> 8) dst[2] = byte(v00 >> 16) dst[3] = byte(v00 >> 24) dst[4] = byte(v01) dst[5] = byte(v01 >> 8) dst[6] = byte(v01 >> 16) dst[7] = byte(v01 >> 24) dst[8] = byte(v02) dst[9] = byte(v02 >> 8) dst[10] = byte(v02 >> 16) dst[11] = byte(v02 >> 24) dst[12] = byte(v03) dst[13] = byte(v03 >> 8) dst[14] = byte(v03 >> 16) dst[15] = byte(v03 >> 24) dst[16] = byte(v04) dst[17] = byte(v04 >> 8) dst[18] = byte(v04 >> 16) dst[19] = byte(v04 >> 24) dst[20] = byte(v05) dst[21] = byte(v05 >> 8) dst[22] = byte(v05 >> 16) dst[23] = byte(v05 >> 24) dst[24] = byte(v06) dst[25] = byte(v06 >> 8) dst[26] = byte(v06 >> 16) dst[27] = byte(v06 >> 24) dst[28] = byte(v07) dst[29] = byte(v07 >> 8) dst[30] = byte(v07 >> 16) dst[31] = byte(v07 >> 24) dst[32] = byte(v08) dst[33] = byte(v08 >> 8) dst[34] = byte(v08 >> 16) dst[35] = byte(v08 >> 24) dst[36] = byte(v09) dst[37] = byte(v09 >> 8) dst[38] = byte(v09 >> 16) dst[39] = byte(v09 >> 24) dst[40] = byte(v10) dst[41] = byte(v10 >> 8) dst[42] = byte(v10 >> 16) dst[43] = byte(v10 >> 24) dst[44] = byte(v11) dst[45] = byte(v11 >> 8) dst[46] = byte(v11 >> 16) dst[47] = byte(v11 >> 24) dst[48] = byte(v12) dst[49] = byte(v12 >> 8) dst[50] = byte(v12 >> 16) dst[51] = byte(v12 >> 24) dst[52] = byte(v13) dst[53] = byte(v13 >> 8) dst[54] = byte(v13 >> 16) dst[55] = byte(v13 >> 24) dst[56] = byte(v14) dst[57] = byte(v14 >> 8) dst[58] = byte(v14 >> 16) dst[59] = byte(v14 >> 24) dst[60] = byte(v15) dst[61] = byte(v15 >> 8) dst[62] = byte(v15 >> 16) dst[63] = byte(v15 >> 24) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/chacha/chacha_test.go000066400000000000000000000051101520706056300270410ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package chacha import ( "bytes" "encoding/hex" "testing" ) var recFail = func(t *testing.T, msg string) { if err := recover(); err == nil { t.Fatalf("Expected error: %s", msg) } } func TestNewCipher(t *testing.T) { mustFail := func(t *testing.T, msg string, nonce *[12]byte, key *[32]byte, rounds int) { defer recFail(t, msg) NewCipher(nonce, key, rounds) } key := new([32]byte) nonce := new([12]byte) mustFail(t, "rounds is 0", nonce, key, 0) mustFail(t, "rounds is not even", nonce, key, 21) } func TestSetCounter(t *testing.T) { var key [32]byte var nonce [12]byte for i := range key { key[i] = byte(i) } buf0, buf1 := make([]byte, 128), make([]byte, 128) c := NewCipher(&nonce, &key, 20) c.XORKeyStream(buf0[:1], buf0[:1]) c.SetCounter(20) c.XORKeyStream(buf0[1:], buf0[1:]) XORKeyStream(buf1[:1], buf1[:1], &nonce, &key, 0, 20) XORKeyStream(buf1[1:], buf1[1:], &nonce, &key, 20, 20) if !bytes.Equal(buf0, buf1) { t.Fatalf("XORKeyStream differ from chacha.XORKeyStream\n XORKeyStream: %s \n chacha.XORKeyStream: %s", hex.EncodeToString(buf1), hex.EncodeToString(buf0)) } } func TestXORKeyStream(t *testing.T) { var key [32]byte var nonce [12]byte for i := range key { key[i] = byte(i) } buf0, buf1 := make([]byte, 256), make([]byte, 256) c := NewCipher(&nonce, &key, 20) c.XORKeyStream(buf0[:1], buf0[:1]) c.XORKeyStream(buf0[1:65], buf0[1:65]) c.XORKeyStream(buf0[65:193], buf0[65:193]) c.XORKeyStream(buf0[193:200], buf0[193:200]) c.XORKeyStream(buf0[200:], buf0[200:]) XORKeyStream(buf1, buf1, &nonce, &key, 0, 20) if !bytes.Equal(buf0, buf1) { t.Fatalf("XORKeyStream differ from chacha.XORKeyStream\n XORKeyStream: %s \n chacha.XORKeyStream: %s", hex.EncodeToString(buf1), hex.EncodeToString(buf0)) } } func TestXORKeyStreamPanic(t *testing.T) { mustFail := func(t *testing.T, msg string, dst, src []byte, nonce *[12]byte, key *[32]byte, counter uint32, rounds int) { defer recFail(t, msg) XORKeyStream(dst, src, nonce, key, counter, rounds) } key := new([32]byte) nonce := new([12]byte) src, dst := make([]byte, 65), make([]byte, 65) mustFail(t, "rounds is 0", dst, src, nonce, key, 0, 0) mustFail(t, "rounds is not even", dst, src, nonce, key, 0, 21) mustFail(t, "len(dst) < len(src)", dst[:len(src)-1], src, nonce, key, 0, 20) c := NewCipher(nonce, key, 20) mustFail2 := func(t *testing.T, msg string, dst, src []byte) { defer recFail(t, msg) c.XORKeyStream(dst, src) } mustFail2(t, "len(dst) < len(src)", dst[:len(src)-1], src) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/chacha20.go000066400000000000000000000023271520706056300247440ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package chacha20 implements the ChaCha stream cipher and // the ChaCha20Poly1305 AEAD construction described in RFC 7539. // // ChaCha20 uses a 32 bit counter and produces 64 byte keystream per // iteration. Following ChaCha20 can en/decrypt up to 2^32 * 64 byte // for one key-nonce combination. Notice that one specific key-nonce // combination must be unique for all time. package chacha20 import ( "crypto/cipher" "github.com/enceve/crypto/chacha20/chacha" ) // The size of the ChaCha20 nonce in bytes. const NonceSize = 12 // XORKeyStream crypts bytes from src to dst using the given key, nonce and counter. Src // and dst may be the same slice but otherwise should not overlap. If len(dst) < len(src) // this function panics. func XORKeyStream(dst, src []byte, nonce *[NonceSize]byte, key *[32]byte, counter uint32) { chacha.XORKeyStream(dst, src, nonce, key, counter, 20) } // NewCipher returns a new cipher.Stream implementing the ChaCha20 // stream cipher. The nonce must be unique for one // key for all time. func NewCipher(nonce *[NonceSize]byte, key *[32]byte) cipher.Stream { return chacha.NewCipher(nonce, key, 20) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/chacha20_test.go000066400000000000000000000027041520706056300260020ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package chacha20 import ( "testing" ) func BenchmarkCipher64B(b *testing.B) { var ( key [32]byte nonce [NonceSize]byte ) c := NewCipher(&nonce, &key) buf := make([]byte, 64) b.SetBytes(64) for i := 0; i < b.N; i++ { c.XORKeyStream(buf, buf) } } func BenchmarkCipher1K(b *testing.B) { var ( key [32]byte nonce [NonceSize]byte ) c := NewCipher(&nonce, &key) buf := make([]byte, 1024) b.SetBytes(1024) for i := 0; i < b.N; i++ { c.XORKeyStream(buf, buf) } } func BenchmarkCipher64K(b *testing.B) { var ( key [32]byte nonce [NonceSize]byte ) c := NewCipher(&nonce, &key) buf := make([]byte, 64*1024) b.SetBytes(64 * 1024) for i := 0; i < b.N; i++ { c.XORKeyStream(buf, buf) } } func BenchmarkXORKeyStream64B(b *testing.B) { var ( key [32]byte nonce [NonceSize]byte ) buf := make([]byte, 64) b.SetBytes(64) for i := 0; i < b.N; i++ { XORKeyStream(buf, buf, &nonce, &key, 0) } } func BenchmarkXORKeyStream1K(b *testing.B) { var ( key [32]byte nonce [NonceSize]byte ) buf := make([]byte, 1024) b.SetBytes(1024) for i := 0; i < b.N; i++ { XORKeyStream(buf, buf, &nonce, &key, 0) } } func BenchmarkXORKeyStream64K(b *testing.B) { var ( key [32]byte nonce [NonceSize]byte ) buf := make([]byte, 64*1024) b.SetBytes(64 * 1024) for i := 0; i < b.N; i++ { XORKeyStream(buf, buf, &nonce, &key, 0) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/chachaPoly1305.go000066400000000000000000000075121520706056300257600ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package chacha20 import ( "crypto/cipher" "crypto/subtle" "errors" "github.com/enceve/crypto" "github.com/enceve/crypto/chacha20/chacha" "github.com/enceve/crypto/poly1305" ) // The max. size of the auth. tag for the ChaCha20Poly1305 AEAD cipher in bytes. const TagSize = poly1305.TagSize // NewChaCha20Poly1305 returns a cipher.AEAD implementing the // ChaCha20Poly1305 construction specified in RFC 7539 with a // 128 bit auth. tag. func NewChaCha20Poly1305(key *[32]byte) cipher.AEAD { c := &aead{tagsize: TagSize} c.key = *key return c } // NewChaCha20Poly1305WithTagSize returns a cipher.AEAD implementing the // ChaCha20Poly1305 construction specified in RFC 7539 with arbitrary tag size. // The tagsize must be between 1 and the TagSize constant. func NewChaCha20Poly1305WithTagSize(key *[32]byte, tagsize int) (cipher.AEAD, error) { if tagsize < 1 || tagsize > TagSize { return nil, errors.New("tag size must be between 1 and 16") } c := &aead{tagsize: tagsize} c.key = *key return c, nil } // The AEAD cipher ChaCha20-Poly1305 type aead struct { key [32]byte tagsize int } func (c *aead) Overhead() int { return c.tagsize } func (c *aead) NonceSize() int { return NonceSize } func (c *aead) Seal(dst, nonce, plaintext, additionalData []byte) []byte { if n := len(nonce); n != NonceSize { panic(crypto.NonceSizeError(n)) } if len(dst) < len(plaintext)+c.tagsize { panic("dst buffer to small") } var Nonce [12]byte copy(Nonce[:], nonce) // create the poly1305 key var polyKey [32]byte chacha.XORKeyStream(polyKey[:], polyKey[:], &Nonce, &(c.key), 0, 20) // encrypt the plaintext n := len(plaintext) chacha.XORKeyStream(dst, plaintext, &Nonce, &(c.key), 1, 20) // authenticate the ciphertext var tag [poly1305.TagSize]byte authenticate(&tag, dst[:n], additionalData, &polyKey) return append(dst[:n], tag[:c.tagsize]...) } func (c *aead) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { if n := len(nonce); n != NonceSize { return nil, crypto.NonceSizeError(n) } if len(ciphertext) < c.tagsize { return nil, crypto.AuthenticationError{} } if len(dst) < len(ciphertext)-c.tagsize { panic("dst buffer to small") } var Nonce [12]byte copy(Nonce[:], nonce) hash := ciphertext[len(ciphertext)-c.tagsize:] ciphertext = ciphertext[:len(ciphertext)-c.tagsize] // create the poly1305 key var polyKey [32]byte chacha.XORKeyStream(polyKey[:], polyKey[:], &Nonce, &(c.key), 0, 20) // authenticate the ciphertext var tag [poly1305.TagSize]byte authenticate(&tag, ciphertext, additionalData, &polyKey) if subtle.ConstantTimeCompare(tag[:c.tagsize], hash[:c.tagsize]) != 1 { return nil, crypto.AuthenticationError{} } // decrypt ciphertext chacha.XORKeyStream(dst, ciphertext, &Nonce, &(c.key), 1, 20) return dst[:len(ciphertext)], nil } // authenticate calculates the poly1305 tag from // the given ciphertext and additional data. func authenticate(out *[TagSize]byte, ciphertext, additionalData []byte, key *[32]byte) { ctLen := uint64(len(ciphertext)) adLen := uint64(len(additionalData)) padAD, padCT := adLen%16, ctLen%16 var buf [16]byte buf[0] = byte(adLen) buf[1] = byte(adLen >> 8) buf[2] = byte(adLen >> 16) buf[3] = byte(adLen >> 24) buf[4] = byte(adLen >> 32) buf[5] = byte(adLen >> 40) buf[6] = byte(adLen >> 48) buf[7] = byte(adLen >> 56) buf[8] = byte(ctLen) buf[9] = byte(ctLen >> 8) buf[10] = byte(ctLen >> 16) buf[11] = byte(ctLen >> 24) buf[12] = byte(ctLen >> 32) buf[13] = byte(ctLen >> 40) buf[14] = byte(ctLen >> 48) buf[15] = byte(ctLen >> 56) poly := poly1305.New(key) poly.Write(additionalData) if padAD > 0 { poly.Write(make([]byte, 16-padAD)) } poly.Write(ciphertext) if padCT > 0 { poly.Write(make([]byte, 16-padCT)) } poly.Write(buf[:]) poly.Sum(out) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/chachaPoly1305_test.go000066400000000000000000000110411520706056300270070ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package chacha20 import "testing" var recFunc = func(t *testing.T, msg string) { if recover() == nil { t.Fatalf("Expected error: %s", msg) } } func TestNewChaCha20Poly1305WithTagSize(t *testing.T) { var key [32]byte _, err := NewChaCha20Poly1305WithTagSize(&key, 0) if err == nil { t.Fatalf("NewChaCha20Poly1305WithTagSize accepted invalid tagsize: %d", 0) } _, err = NewChaCha20Poly1305WithTagSize(&key, 17) if err == nil { t.Fatalf("NewChaCha20Poly1305WithTagSize accepted invalid tagsize: %d", 0) } } func TestOverhead(t *testing.T) { var key [32]byte c := NewChaCha20Poly1305(&key) if o := c.Overhead(); o != TagSize { t.Fatalf("Expected %d but Overhead() returned %d", TagSize, o) } c, err := NewChaCha20Poly1305WithTagSize(&key, 12) if err != nil { t.Fatalf("Failed to create ChaCha20Poly1305 instance: %s", err) } if o := c.Overhead(); o != 12 { t.Fatalf("Expected %d but Overhead() returned %d", 12, o) } } func TestNonceSize(t *testing.T) { var key [32]byte c := NewChaCha20Poly1305(&key) if n := c.NonceSize(); n != NonceSize { t.Fatalf("Expected %d but NonceSize() returned %d", TagSize, n) } } func TestSeal(t *testing.T) { var key [32]byte c := NewChaCha20Poly1305(&key) var ( nonce [NonceSize]byte src [64]byte dst [64 + TagSize]byte ) mustFail := func(msg string, dst, nonce, src []byte) { defer recFunc(t, msg) c.Seal(dst, nonce, src, nil) } mustFail("nonce size is invalid", dst[:], nonce[:NonceSize-1], src[:]) mustFail("dst length invalid", dst[:len(dst)-2], nonce[:], src[:]) } func TestOpen(t *testing.T) { var key [32]byte c := NewChaCha20Poly1305(&key) var ( nonce [NonceSize]byte src [64]byte dst [64 + TagSize]byte ) _, err := c.Open(dst[:], nonce[:NonceSize-1], src[:], nil) if err == nil { t.Fatal("Open() accepted invalid nonce size") } _, err = c.Open(dst[:], nonce[:], src[:TagSize-1], nil) if err == nil { t.Fatal("Open() accepted invalid ciphertext length") } mustFail := func(msg string, dst, nonce, src []byte) { defer recFunc(t, msg) c.Open(dst, nonce, src, nil) } mustFail("dst length invalid", dst[:len(src)-TagSize-1], nonce[:], src[:]) // Check tag verification c.Seal(dst[:], nonce[:], src[:], nil) dst[len(src)+1] += 1 // modify tag _, err = c.Open(src[:], nonce[:], dst[:], nil) if err == nil { t.Fatal("Open() accepted invalid auth. tag") } } func BenchmarkSeal64B(b *testing.B) { var key [32]byte var nonce [12]byte c := NewChaCha20Poly1305(&key) msg := make([]byte, 64) dst := make([]byte, len(msg)+TagSize) data := make([]byte, 32) b.SetBytes(int64(len(msg))) for i := 0; i < b.N; i++ { dst = c.Seal(dst, nonce[:], msg, data) } } func BenchmarkSeal1K(b *testing.B) { var key [32]byte var nonce [12]byte c := NewChaCha20Poly1305(&key) msg := make([]byte, 1024) dst := make([]byte, len(msg)+TagSize) data := make([]byte, 32) b.SetBytes(int64(len(msg))) for i := 0; i < b.N; i++ { dst = c.Seal(dst, nonce[:], msg, data) } } func BenchmarkSeal64K(b *testing.B) { var key [32]byte var nonce [12]byte c := NewChaCha20Poly1305(&key) msg := make([]byte, 64*1024) dst := make([]byte, len(msg)+TagSize) data := make([]byte, 32) b.SetBytes(int64(len(msg))) for i := 0; i < b.N; i++ { dst = c.Seal(dst, nonce[:], msg, data) } } func BenchmarkOpen64B(b *testing.B) { var key [32]byte var nonce [12]byte c := NewChaCha20Poly1305(&key) msg := make([]byte, 64) dst := make([]byte, len(msg)) ciphertext := make([]byte, len(msg)+TagSize) data := make([]byte, 32) ciphertext = c.Seal(ciphertext, nonce[:], msg, data) b.SetBytes(int64(len(msg))) for i := 0; i < b.N; i++ { dst, _ = c.Open(dst, nonce[:], ciphertext, data) } } func BenchmarkOpen1K(b *testing.B) { var key [32]byte var nonce [12]byte c := NewChaCha20Poly1305(&key) msg := make([]byte, 1024) dst := make([]byte, len(msg)) ciphertext := make([]byte, len(msg)+TagSize) data := make([]byte, 32) ciphertext = c.Seal(ciphertext, nonce[:], msg, data) b.SetBytes(int64(len(msg))) for i := 0; i < b.N; i++ { dst, _ = c.Open(dst, nonce[:], ciphertext, data) } } func BenchmarkOpen64K(b *testing.B) { var key [32]byte var nonce [12]byte c := NewChaCha20Poly1305(&key) msg := make([]byte, 64*1024) dst := make([]byte, len(msg)) ciphertext := make([]byte, len(msg)+TagSize) data := make([]byte, 32) ciphertext = c.Seal(ciphertext, nonce[:], msg, data) b.SetBytes(int64(len(msg))) for i := 0; i < b.N; i++ { dst, _ = c.Open(dst, nonce[:], ciphertext, data) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/chacha20/vectors_test.go000066400000000000000000000164121520706056300261170ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package chacha20 import ( "bytes" "encoding/hex" "testing" ) func fromHex(s string) []byte { b, err := hex.DecodeString(s) if err != nil { panic(err) } return b } // Test vector from: // https://tools.ietf.org/html/rfc7539#section-2.8.1 var chacha20TestVectors = []struct { key, nonce string msg, ciphertext string ctr uint32 }{ { key: "0000000000000000000000000000000000000000000000000000000000000000", nonce: "000000000000000000000000", msg: "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000", ciphertext: "76b8e0ada0f13d90405d6ae55386bd28" + "bdd219b8a08ded1aa836efcc8b770dc7" + "da41597c5157488d7724e03fb8d84a37" + "6a43b8f41518a11cc387b669b2ee6586", ctr: 0, }, { key: "0000000000000000000000000000000000000000000000000000000000000001", nonce: "000000000000000000000002", msg: "416e79207375626d697373696f6e2074" + "6f20746865204945544620696e74656e" + "6465642062792074686520436f6e7472" + "696275746f7220666f72207075626c69" + "636174696f6e20617320616c6c206f72" + "2070617274206f6620616e2049455446" + "20496e7465726e65742d447261667420" + "6f722052464320616e6420616e792073" + "746174656d656e74206d616465207769" + "7468696e2074686520636f6e74657874" + "206f6620616e20494554462061637469" + "7669747920697320636f6e7369646572" + "656420616e20224945544620436f6e74" + "7269627574696f6e222e205375636820" + "73746174656d656e747320696e636c75" + "6465206f72616c2073746174656d656e" + "747320696e2049455446207365737369" + "6f6e732c2061732077656c6c20617320" + "7772697474656e20616e6420656c6563" + "74726f6e696320636f6d6d756e696361" + "74696f6e73206d61646520617420616e" + "792074696d65206f7220706c6163652c" + "20776869636820617265206164647265" + "7373656420746f", ciphertext: "a3fbf07df3fa2fde4f376ca23e827370" + "41605d9f4f4f57bd8cff2c1d4b7955ec" + "2a97948bd3722915c8f3d337f7d37005" + "0e9e96d647b7c39f56e031ca5eb6250d" + "4042e02785ececfa4b4bb5e8ead0440e" + "20b6e8db09d881a7c6132f420e527950" + "42bdfa7773d8a9051447b3291ce1411c" + "680465552aa6c405b7764d5e87bea85a" + "d00f8449ed8f72d0d662ab052691ca66" + "424bc86d2df80ea41f43abf937d3259d" + "c4b2d0dfb48a6c9139ddd7f76966e928" + "e635553ba76c5c879d7b35d49eb2e62b" + "0871cdac638939e25e8a1e0ef9d5280f" + "a8ca328b351c3c765989cbcf3daa8b6c" + "cc3aaf9f3979c92b3720fc88dc95ed84" + "a1be059c6499b9fda236e7e818b04b0b" + "c39c1e876b193bfe5569753f88128cc0" + "8aaa9b63d1a16f80ef2554d7189c411f" + "5869ca52c5b83fa36ff216b9c1d30062" + "bebcfd2dc5bce0911934fda79a86f6e6" + "98ced759c3ff9b6477338f3da4f9cd85" + "14ea9982ccafb341b2384dd902f3d1ab" + "7ac61dd29c6f21ba5b862f3730e37cfd" + "c4fd806c22f221", ctr: 1, }, { key: "1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0", nonce: "000000000000000000000002", msg: "2754776173206272696c6c69672c2061" + "6e642074686520736c6974687920746f" + "7665730a446964206779726520616e64" + "2067696d626c6520696e207468652077" + "6162653a0a416c6c206d696d73792077" + "6572652074686520626f726f676f7665" + "732c0a416e6420746865206d6f6d6520" + "7261746873206f757467726162652e", ciphertext: "62e6347f95ed87a45ffae7426f27a1df" + "5fb69110044c0d73118effa95b01e5cf" + "166d3df2d721caf9b21e5fb14c616871" + "fd84c54f9d65b283196c7fe4f60553eb" + "f39c6402c42234e32a356b3e764312a6" + "1a5532055716ead6962568f87d3f3f77" + "04c6a8d1bcd1bf4d50d6154b6da731b1" + "87b58dfd728afa36757a797ac188d1", ctr: 42, }, } func TestVectors(t *testing.T) { for i, v := range chacha20TestVectors { key := fromHex(v.key) nonce := fromHex(v.nonce) msg := fromHex(v.msg) ciphertext := fromHex(v.ciphertext) var ( Key [32]byte Nonce [12]byte ) copy(Key[:], key) copy(Nonce[:], nonce) buf := make([]byte, len(ciphertext)) XORKeyStream(buf, msg, &Nonce, &Key, v.ctr) if !bytes.Equal(buf, ciphertext) { t.Fatalf("Test vector %d :\nXORKeyStream() produces unexpected keystream:\nXORKeyStream(): %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(ciphertext)) } c := NewCipher(&Nonce, &Key) var trash [64]byte for i := 0; i < int(v.ctr); i++ { c.XORKeyStream(trash[:], trash[:]) } c.XORKeyStream(buf[:], msg[:]) if !bytes.Equal(buf, ciphertext) { t.Fatalf("Test vector %d :\nc.XORKeyStream() produces unexpected keystream:\nc.XORKeyStream(): %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(ciphertext)) } } } // Test vector from: // https://tools.ietf.org/html/rfc7539#section-2.8.2 var aeadTestVectors = []struct { key, nonce, data string msg, ciphertext string tagSize int }{ { key: "808182838485868788898a8b8c8d8e8f" + "909192939495969798999a9b9c9d9e9f", nonce: "070000004041424344454647", data: "50515253c0c1c2c3c4c5c6c7", msg: "4c616469657320616e642047656e746c656d656e206f662074686520636c6173" + "73206f66202739393a204966204920636f756c64206f6666657220796f75206f" + "6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73" + "637265656e20776f756c642062652069742e", ciphertext: "d31a8d34648e60db7b86afbc53ef7ec2" + "a4aded51296e08fea9e2b5a736ee62d6" + "3dbea45e8ca9671282fafb69da92728b" + "1a71de0a9e060b2905d6a5b67ecd3b36" + "92ddbd7f2d778b8c9803aee328091b58" + "fab324e4fad675945585808b4831d7bc" + "3ff4def08e4b7a9de576d26586cec64b" + "6116" + "1ae10b594f09e26a7e902ecbd0600691", // poly 1305 tag tagSize: TagSize, }, { key: "808182838485868788898a8b8c8d8e8f" + "909192939495969798999a9b9c9d9e9f", nonce: "070000004041424344454647", data: "50515253c0c1c2c3c4c5c6c7", msg: "4c616469657320616e642047656e746c656d656e206f662074686520636c6173" + "73206f66202739393a204966204920636f756c64206f6666657220796f75206f" + "6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73" + "637265656e20776f756c642062652069742e", ciphertext: "d31a8d34648e60db7b86afbc53ef7ec2" + "a4aded51296e08fea9e2b5a736ee62d6" + "3dbea45e8ca9671282fafb69da92728b" + "1a71de0a9e060b2905d6a5b67ecd3b36" + "92ddbd7f2d778b8c9803aee328091b58" + "fab324e4fad675945585808b4831d7bc" + "3ff4def08e4b7a9de576d26586cec64b" + "6116" + "1ae10b594f09e26a7e902ecb", // poly 1305 tag tagSize: 12, }, } func TestAEADVectors(t *testing.T) { for i, v := range aeadTestVectors { key := fromHex(v.key) nonce := fromHex(v.nonce) msg := fromHex(v.msg) data := fromHex(v.data) ciphertext := fromHex(v.ciphertext) var Key [32]byte copy(Key[:], key) c, err := NewChaCha20Poly1305WithTagSize(&Key, v.tagSize) if err != nil { t.Fatalf("Test vector %d: Failed to create AEAD instance: %s", i, err) } buf := make([]byte, len(ciphertext)) c.Seal(buf, nonce, msg, data) if !bytes.Equal(buf, ciphertext) { t.Fatalf("TestVector %d Seal failed:\nFound : %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(ciphertext)) } buf, err = c.Open(buf, nonce, buf, data) if err != nil { t.Fatalf("TestVector %d: Open failed - Cause: %s", i, err) } if !bytes.Equal(msg, buf) { t.Fatalf("TestVector %d Open failed:\nFound : %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(msg)) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/cipher/000077500000000000000000000000001520706056300227415ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/cipher/eax.go000066400000000000000000000105131520706056300240450ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package cipher implements additional block cipher modes // that can be wrapped around low-level block cipher implementations. // For standard block cipher modes see: https://golang.org/pkg/crypto/cipher package cipher import ( "crypto/cipher" "crypto/subtle" "errors" "hash" "github.com/enceve/crypto" "github.com/enceve/crypto/cmac" ) const ( nTag = 0x0 // The nonce tag constant hTag = 0x1 // The additional data tag constant cTag = 0x2 // The ciphertext tag constant ) // The EAX cipher type eaxCipher struct { blockCipher cipher.Block ctr, block []byte mac hash.Hash size int } // NewEAX returns a cipher.AEAD wrapping the cipher.Block. // EAX is a two pass-scheme AEAD cipher with provable security. // For authentication EAX uses CMac (OMAC1). // The tagsize argument specifies the number of bytes of the auth. tag // and must be between 1 and the block size of the cipher. // This function returns a non-nil error if the given block cipher // is not supported by CMac (see crypto/cmac for details) func NewEAX(c cipher.Block, tagsize int) (cipher.AEAD, error) { m, err := cmac.New(c) if err != nil { return nil, err } if tagsize < 1 || tagsize > c.BlockSize() { return nil, errors.New("tagSize must between 1 and BlockSize() of the given cipher") } return &eaxCipher{ blockCipher: c, mac: m, ctr: make([]byte, c.BlockSize()), block: make([]byte, c.BlockSize()), size: tagsize, }, nil } func (c *eaxCipher) NonceSize() int { return c.blockCipher.BlockSize() } func (c *eaxCipher) Overhead() int { return c.size } func (c *eaxCipher) Seal(dst, nonce, plaintext, additionalData []byte) []byte { if n := len(nonce); n != c.blockCipher.BlockSize() { panic(crypto.NonceSizeError(n)) } if len(dst) < len(plaintext) { panic("dst buffer to small") } tag := make([]byte, c.mac.BlockSize()) // process nonce tag[len(tag)-1] = nTag c.mac.Write(tag) c.mac.Write(nonce) authNonce := c.mac.Sum(nil) c.mac.Reset() // process additional data tag[len(tag)-1] = hTag c.mac.Write(tag) c.mac.Write(additionalData) authData := c.mac.Sum(nil) c.mac.Reset() // encrypt n := len(plaintext) copy(c.ctr, authNonce) // set the ctr-mode nonce c.ctrCrypt(dst, plaintext) // process ciphertext tag[len(tag)-1] = cTag c.mac.Write(tag) c.mac.Write(dst[:n]) tag = c.mac.Sum(tag[:0]) c.mac.Reset() for i := range tag { tag[i] ^= authData[i] ^ authNonce[i] } return append(dst[:n], tag[:c.size]...) } func (c *eaxCipher) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { if n := len(nonce); n != c.blockCipher.BlockSize() { return nil, crypto.NonceSizeError(n) } if len(ciphertext) < c.size { return nil, crypto.AuthenticationError{} } if len(dst) < len(ciphertext)-c.mac.Size() { panic("dst buffer to small") } hash := ciphertext[len(ciphertext)-c.size:] ciphertext = ciphertext[:len(ciphertext)-c.size] tag := make([]byte, c.mac.BlockSize()) // process nonce tag[len(tag)-1] = nTag c.mac.Write(tag) c.mac.Write(nonce) authNonce := c.mac.Sum(nil) c.mac.Reset() // process additional data tag[len(tag)-1] = hTag c.mac.Write(tag) c.mac.Write(additionalData) authData := c.mac.Sum(nil) c.mac.Reset() // process ciphertext tag[len(tag)-1] = cTag c.mac.Write(tag) c.mac.Write(ciphertext) tag = c.mac.Sum(tag[:0]) c.mac.Reset() for i := range tag { tag[i] ^= authData[i] ^ authNonce[i] } if subtle.ConstantTimeCompare(tag[:c.size], hash) != 1 { return nil, crypto.AuthenticationError{} } // decrypt n := len(ciphertext) copy(c.ctr, authNonce) // set the ctr-mode nonce c.ctrCrypt(dst, ciphertext) return dst[:n], nil } // ctrCrypt encrypts the bytes in src with the CTR mode and writes // the ciphertext into dst func (c *eaxCipher) ctrCrypt(dst, src []byte) { length := len(src) bs := c.blockCipher.BlockSize() n := length & (^(length - bs)) for i := 0; i < n; i += bs { j := i + bs c.blockCipher.Encrypt(c.block, c.ctr) crypto.XOR(dst[i:j], src[i:j], c.block) // Increment counter for k := len(c.ctr) - 1; k >= 0; k-- { c.ctr[k]++ if c.ctr[k] != 0 { break } } } if n < length { c.blockCipher.Encrypt(c.block, c.ctr) crypto.XOR(dst[n:], src[n:], c.block) } // no reset of ctr needed - Seal or Open does this for us } golang-github-enceve-crypto-0.0~git20160707.34d48bb/cipher/eax_test.go000066400000000000000000000045421520706056300251110ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package cipher import ( "crypto/aes" "testing" ) // Benchmarks func BenchmarkSeal_64B(b *testing.B) { block, err := aes.NewCipher(make([]byte, 16)) if err != nil { b.Fatalf("Failed to create AES-128 instance: %s", err) } nonce := make([]byte, aes.BlockSize) c, err := NewEAX(block, block.BlockSize()) if err != nil { b.Fatalf("Failed to create AES-128-EAX instance: %s", err) } msg := make([]byte, 64) dst := make([]byte, len(msg)+aes.BlockSize) data := make([]byte, 8) b.SetBytes(64) for i := 0; i < b.N; i++ { dst = c.Seal(dst, nonce, msg, data) } } func BenchmarkSeal_1K(b *testing.B) { block, err := aes.NewCipher(make([]byte, 16)) if err != nil { b.Fatalf("Failed to create AES-128 instance: %s", err) } nonce := make([]byte, aes.BlockSize) c, err := NewEAX(block, block.BlockSize()) if err != nil { b.Fatalf("Failed to create AES-128-EAX instance: %s", err) } msg := make([]byte, 1024) dst := make([]byte, len(msg)+aes.BlockSize) data := make([]byte, 8) b.SetBytes(1024) for i := 0; i < b.N; i++ { dst = c.Seal(dst, nonce, msg, data) } } func BenchmarkOpen_64B(b *testing.B) { block, err := aes.NewCipher(make([]byte, 16)) if err != nil { b.Fatalf("Failed to create AES-128 instance: %s", err) } nonce := make([]byte, aes.BlockSize) c, err := NewEAX(block, block.BlockSize()) if err != nil { b.Fatalf("Failed to create AES-128-EAX instance: %s", err) } msg := make([]byte, 64) dst := make([]byte, len(msg)) ciphertext := make([]byte, len(msg)+aes.BlockSize) data := make([]byte, 8) ciphertext = c.Seal(ciphertext, nonce, msg, data) b.SetBytes(64) for i := 0; i < b.N; i++ { dst, _ = c.Open(dst, nonce, ciphertext, data) } } func BenchmarkOpen_1K(b *testing.B) { block, err := aes.NewCipher(make([]byte, 16)) if err != nil { b.Fatalf("Failed to create AES-128 instance: %s", err) } nonce := make([]byte, aes.BlockSize) c, err := NewEAX(block, block.BlockSize()) if err != nil { b.Fatalf("Failed to create AES-128-EAX instance: %s", err) } msg := make([]byte, 1024) dst := make([]byte, len(msg)) ciphertext := make([]byte, len(msg)+aes.BlockSize) data := make([]byte, 8) ciphertext = c.Seal(ciphertext, nonce, msg, data) b.SetBytes(1024) for i := 0; i < b.N; i++ { dst, _ = c.Open(dst, nonce, ciphertext, data) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/cipher/vectors_test.go000066400000000000000000000066411520706056300260230ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package cipher import ( "bytes" "crypto/aes" "encoding/hex" "testing" ) type testVector struct { msg, key, nonce, data string ciphertext string macSize int } // EAX-AES test vectors from // http://web.cs.ucdavis.edu/~rogaway/papers/eax.pdf var vectors = []testVector{ testVector{ msg: "", key: "233952DEE4D5ED5F9B9C6D6FF80FF478", nonce: "62EC67F9C3A4A407FCB2A8C49031A8B3", data: "6BFB914FD07EAE6B", ciphertext: "E037830E8389F27B025A2D6527E79D01", macSize: 16, }, testVector{ msg: "F7FB", key: "91945D3F4DCBEE0BF45EF52255F095A4", nonce: "BECAF043B0A23D843194BA972C66DEBD", data: "FA3BFD4806EB53FA", ciphertext: "19DD5C4C9331049D0BDAB0277408F67967E5", macSize: 16, }, testVector{ msg: "1A47CB4933", key: "01F74AD64077F2E704C0F60ADA3DD523", nonce: "70C3DB4F0D26368400A10ED05D2BFF5E", data: "234A3463C1264AC6", ciphertext: "D851D5BAE03A59F238A23E39199DC9266626C40F80", macSize: 16, }, testVector{ msg: "1A47CB4933", key: "01F74AD64077F2E704C0F60ADA3DD523", nonce: "70C3DB4F0D26368400A10ED05D2BFF5E", data: "234A3463C1264AC6", ciphertext: "D851D5BAE03A59F238A23E39199DC9266626C4", macSize: 14, }, testVector{ msg: "8B0A79306C9CE7ED99DAE4F87F8DD61636", key: "7C77D6E813BED5AC98BAA417477A2E7D", nonce: "1A8C98DCD73D38393B2BF1569DEEFC19", data: "65D2017990D62528", ciphertext: "02083E3979DA014812F59F11D52630DA30137327D10" + "649B0AA6E1C181DB617D7F2", macSize: 16, }, testVector{ msg: "8B0A79306C9CE7ED99DAE4F87F8DD61636", key: "7C77D6E813BED5AC98BAA417477A2E7D", nonce: "1A8C98DCD73D38393B2BF1569DEEFC19", data: "65D2017990D62528", ciphertext: "02083E3979DA014812F59F11D52630DA30137327D10" + "649B0AA6E1C181D", macSize: 12, }, } func TestVectors(t *testing.T) { for i, v := range vectors { msg, err := hex.DecodeString(v.msg) if err != nil { t.Fatalf("TestVector %d: Failed to decode hex msg: %s", i, err) } key, err := hex.DecodeString(v.key) if err != nil { t.Fatalf("TestVector %d: Failed to decode hex key: %s", i, err) } nonce, err := hex.DecodeString(v.nonce) if err != nil { t.Fatalf("TestVector %d: Failed to decode hex nonce: %s", i, err) } data, err := hex.DecodeString(v.data) if err != nil { t.Fatalf("TestVector %d: Failed to decode hex data: %s", i, err) } ciphertext, err := hex.DecodeString(v.ciphertext) if err != nil { t.Fatalf("TestVector %d: Failed to decode hex ciphertext: %s", i, err) } cAES, err := aes.NewCipher(key) if err != nil { t.Fatalf("TestVector %d: Failed to create AES instance: %s", i, err) } eax, err := NewEAX(cAES, v.macSize) if err != nil { t.Fatalf("TestVector %d: Failed to create EAX instance: %s", i, err) } buf := make([]byte, len(ciphertext)) buf = eax.Seal(buf, nonce, msg, data) if !bytes.Equal(buf, ciphertext) { t.Fatalf("TestVector %d Seal failed:\nFound : %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(ciphertext)) } buf, err = eax.Open(buf, nonce, buf, data) if err != nil { t.Fatalf("TestVector %d: Open failed: %s", i, err) } if !bytes.Equal(buf, msg) { t.Fatalf("TestVector %d Open failed:\nFound : %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(msg)) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/cmac/000077500000000000000000000000001520706056300223725ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/cmac/cmac.go000066400000000000000000000104641520706056300236310ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package cmac implements the fast CMac MAC based on // a block cipher. This mode of operation fixes security // deficiencies of CBC-MAC (CBC-MAC is secure only for // fixed-length messages). CMac is equal to OMAC1. // This implementations supports block ciphers with a // block size of: // - 64 bit (8 byte) // - 128 bit (16 byte) // - 256 bit (32 byte) // - 512 bit (64 byte) // - 1024 bit (128 byte) // Common ciphers like AES, Serpent etc. operate on 128 bit // blocks. 256, 512 and 1024 are supported for the Threefish // tweakable block cipher. Ciphers with 64 bit blocks are // supported, but not recommened. // CMac (using AES) is specified in RFC 4493. package cmac import ( "crypto/cipher" "crypto/subtle" "errors" "hash" "github.com/enceve/crypto" ) const ( // minimal irreducible polynomial for blocksize p64 = 0x1b // for 64 bit block ciphers p128 = 0x87 // for 128 bit block ciphers (like AES) p256 = 0x425 // special for large block ciphers (Threefish) p512 = 0x125 // special for large block ciphers (Threefish) p1024 = 0x80043 // special for large block ciphers (Threefish) ) // Sum computes the CMac checksum of msg using the cipher.Block. // If the block cipher is not supported by CMac (see package doc), // a non-nil error is returned. func Sum(msg []byte, c cipher.Block) ([]byte, error) { mac, err := New(c) if err != nil { return nil, err } mac.Write(msg) return mac.Sum(nil), nil } // Verify computes the CMac checksum of msg and compares it with the // given mac. This functions returns true if and only if the given mac // is equal to computed one. If the block cipher is not supported // by CMac (see package doc), this function returns false. func Verify(mac, msg []byte, c cipher.Block) bool { sum, err := Sum(msg, c) if err != nil { return false } return subtle.ConstantTimeCompare(mac, sum) == 1 } // New returns a hash.Hash computing the CMac checksum. // If the block cipher is not supported by CMac // (see package doc), a non-nil error is returned. func New(c cipher.Block) (hash.Hash, error) { if c == nil { return nil, errors.New("the cipher.Block must not be nil") } bs := c.BlockSize() var p int switch bs { default: return nil, errors.New("cipher block size not supported") case 8: p = p64 case 16: p = p128 case 32: p = p256 case 64: p = p512 case 128: p = p1024 } m := &macFunc{ cipher: c, k0: make([]byte, bs), k1: make([]byte, bs), buf: make([]byte, bs), } c.Encrypt(m.k0, m.k0) v := shift(m.k0, m.k0) m.k0[bs-1] ^= byte(subtle.ConstantTimeSelect(v, p, 0)) v = shift(m.k1, m.k0) m.k1[bs-1] ^= byte(subtle.ConstantTimeSelect(v, p, 0)) return m, nil } // The CMac message auth. function type macFunc struct { cipher cipher.Block k0, k1 []byte buf []byte off int } func (h *macFunc) Size() int { return h.cipher.BlockSize() } func (h *macFunc) BlockSize() int { return h.cipher.BlockSize() } func (h *macFunc) Reset() { for i := range h.buf { h.buf[i] = 0 } h.off = 0 } func (h *macFunc) Write(msg []byte) (int, error) { bs := h.BlockSize() n := len(msg) if h.off > 0 { dif := bs - h.off if n > dif { crypto.XOR(h.buf[h.off:], h.buf[h.off:], msg[:dif]) msg = msg[dif:] h.cipher.Encrypt(h.buf, h.buf) h.off = 0 } else { crypto.XOR(h.buf[h.off:], h.buf[h.off:], msg) h.off += n return n, nil } } if length := len(msg); length > bs { nn := length & (^(bs - 1)) if length == nn { nn -= bs } for i := 0; i < nn; i += bs { crypto.XOR(h.buf, h.buf, msg[i:i+bs]) h.cipher.Encrypt(h.buf, h.buf) } msg = msg[nn:] } if length := len(msg); length > 0 { crypto.XOR(h.buf[h.off:], h.buf[h.off:], msg) h.off += length } return n, nil } func (h *macFunc) Sum(b []byte) []byte { bs := h.cipher.BlockSize() // Don't change the buffer so the // caller can keep writing and suming. hash := make([]byte, bs) k := h.k0 if h.off < bs { k = h.k1 } crypto.XOR(hash, k, h.buf) if h.off < h.cipher.BlockSize() { hash[h.off] ^= 0x80 } h.cipher.Encrypt(hash, hash) return append(b, hash...) } func shift(dst, src []byte) int { var b, bit byte for i := len(src) - 1; i >= 0; i-- { // a range would be nice bit = src[i] >> 7 dst[i] = src[i]<<1 | b b = bit } return int(b) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/cmac/cmac_test.go000066400000000000000000000120761520706056300246710ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package cmac import ( "bytes" "crypto/aes" "encoding/hex" "testing" ) // A cipher.Block mock, simulating block ciphers // with any block size. type dummyCipher int func (c dummyCipher) BlockSize() int { return int(c) } func (c dummyCipher) Encrypt(dst, src []byte) { copy(dst, src) } func (c dummyCipher) Decrypt(dst, src []byte) { copy(dst, src) } func TestNew(t *testing.T) { _, err := New(nil) if err == nil { t.Fatal("CMac allowed nil for block cipher") } var ciphers = [5]dummyCipher{8, 16, 32, 64, 128} for _, c := range ciphers { _, err := New(c) if err != nil { t.Fatalf("BlockSize: %d, Failed to create CMac instance: %s", int(c), err) } } _, err = New(dummyCipher(20)) if err == nil { t.Fatalf("CMac allowed invalid block size: %d", 20) } } func TestBlockSize(t *testing.T) { c, err := aes.NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Could not create AES instance: %s", err) } h, err := New(c) if err != nil { t.Fatalf("Could not create CMac instance: %s", err) } if bs := h.BlockSize(); bs != c.BlockSize() { t.Fatalf("BlockSize() returned: %d - but expected: %d", bs, c.BlockSize()) } } func TestSize(t *testing.T) { c, err := aes.NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Could not create AES instance: %s", err) } h, err := New(c) if err != nil { t.Fatalf("Could not create CMac instance: %s", err) } if bs := h.Size(); bs != c.BlockSize() { t.Fatalf("Size() returned: %d - but expected: %d", bs, c.BlockSize()) } } func TestReset(t *testing.T) { cipher, err := aes.NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Could not create AES instance: %s", err) } h, err := New(cipher) if err != nil { t.Fatalf("Failed to use CMac with the specified cipher") } c, ok := h.(*macFunc) if !ok { t.Fatal("Impossible situation: New returns no CMac struct") } orig := *c // copy c.Write(make([]byte, c.BlockSize()+1)) c.Reset() if !bytes.Equal(c.buf, orig.buf) { t.Fatalf("Reseted buf field: %d - but expected: %d", c.buf, orig.buf) } if !bytes.Equal(c.k0, orig.k0) { t.Fatalf("Reseted k0 field: %d - but expected: %d", c.k0, orig.k0) } if !bytes.Equal(c.k1, orig.k1) { t.Fatalf("Reseted k1 field: %d - but expected: %d", c.k1, orig.k1) } if c.off != orig.off { t.Fatalf("Reseted off field: %d - but expected: %d", c.off, orig.off) } if c.cipher != orig.cipher { t.Fatalf("Reseted cipher field: %v - but expected: %v", c.cipher, orig.cipher) } } func TestWrite(t *testing.T) { c, err := aes.NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Could not create AES instance: %s", err) } h, err := New(c) if err != nil { t.Fatalf("Failed to create CMac instance: %s", err) } var msg1 []byte msg0 := make([]byte, 64) for i := range msg0 { h.Write(msg0[:i]) msg1 = append(msg1, msg0[:i]...) } tag0 := h.Sum(nil) tag1, err := Sum(msg1, c) if err != nil { t.Fatalf("Failed to compute CMac tag: %s", err) } if !bytes.Equal(tag0, tag1) { t.Fatalf("Sum differ from cmac.Sum\n Sum: %s \n cmac.Sum: %s", hex.EncodeToString(tag0), hex.EncodeToString(tag1)) } } func TestSum(t *testing.T) { c, err := aes.NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Could not create AES instance: %s", err) } msg := make([]byte, 64) for i := range msg { h, err := New(c) if err != nil { t.Fatalf("Iteration %d: Failed to create CMac instance: %s", i, err) } h.Write(msg[:i]) tag0 := h.Sum(nil) tag1, err := Sum(msg[:i], c) if err != nil { t.Fatalf("Iteration %d: Failed to compute CMac tag: %s", i, err) } if !bytes.Equal(tag0, tag1) { t.Fatalf("Iteration %d: Sum differ from cmac.Sum\n Sum: %s \n cmac.Sum %s", i, hex.EncodeToString(tag0), hex.EncodeToString(tag1)) } } _, err = Sum(nil, dummyCipher(20)) if err == nil { t.Fatalf("cmac.Sum allowed invalid block size: %d", 20) } } func TestVerify(t *testing.T) { var mac [16]byte mac[0] = 128 if Verify(mac[:], nil, dummyCipher(20)) { t.Fatalf("cmac.Verify allowed invalid block size: %d", 20) } } // Benchmarks func BenchmarkWrite_16B(b *testing.B) { benchmarkWrite(b, 16) } func BenchmarkWrite_1K(b *testing.B) { benchmarkWrite(b, 1024) } func BenchmarkWrite_64K(b *testing.B) { benchmarkWrite(b, 64*1024) } func BenchmarkSum_16B(b *testing.B) { benchmarkSum(b, 16) } func BenchmarkSum_1K(b *testing.B) { benchmarkSum(b, 1024) } func BenchmarkSum_64K(b *testing.B) { benchmarkSum(b, 64*1024) } func benchmarkWrite(b *testing.B, nBytes int) { c, err := aes.NewCipher(make([]byte, 16)) if err != nil { b.Fatalf("Failed to create AES instance: %s", err) } h, err := New(c) if err != nil { b.Fatalf("Failed to create CMac instance: %s", err) } buf := make([]byte, nBytes) b.SetBytes(int64(nBytes)) for i := 0; i < b.N; i++ { h.Write(buf) } } func benchmarkSum(b *testing.B, nBytes int) { c, err := aes.NewCipher(make([]byte, 16)) if err != nil { b.Fatalf("Failed to create AES instance: %s", err) } buf := make([]byte, nBytes) b.SetBytes(int64(nBytes)) for i := 0; i < b.N; i++ { Sum(buf, c) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/cmac/vectors_test.go000066400000000000000000000046751520706056300254610ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package cmac import ( "bytes" "crypto/aes" "encoding/hex" "testing" ) // Test vectors for CMac-AES from NIST // http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf // Appendix D var testVectors = []struct { key, msg, hash string }{ // AES-128 vectors { key: "2b7e151628aed2a6abf7158809cf4f3c", msg: "", hash: "bb1d6929e95937287fa37d129b756746", }, { key: "2b7e151628aed2a6abf7158809cf4f3c", msg: "6bc1bee22e409f96e93d7e117393172a", hash: "070a16b46b4d4144f79bdd9dd04a287c", }, { key: "2b7e151628aed2a6abf7158809cf4f3c", msg: "6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411", hash: "dfa66747de9ae63030ca32611497c827", }, // AES-256 vectors { key: "603deb1015ca71be2b73aef0857d7781" + "1f352c073b6108d72d9810a30914dff4", msg: "", hash: "028962f61b7bf89efc6b551f4667d983", }, { key: "603deb1015ca71be2b73aef0857d7781" + "1f352c073b6108d72d9810a30914dff4", msg: "6bc1bee22e409f96e93d7e117393172a", hash: "28a7023f452e8f82bd4bf28d8c37c35c", }, { key: "603deb1015ca71be2b73aef0857d7781" + "1f352c073b6108d72d9810a30914dff4", msg: "6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411", hash: "aaf3d8f1de5640c232f5b169b9c911e6", }, } func TestVectors(t *testing.T) { for i, v := range testVectors { key, err := hex.DecodeString(v.key) if err != nil { t.Fatalf("Test vector %d: Failed to decode hex key: %s", i, err) } msg, err := hex.DecodeString(v.msg) if err != nil { t.Fatalf("Test vector %d: Failed to decode hex msg: %s", i, err) } hash, err := hex.DecodeString(v.hash) if err != nil { t.Fatalf("Test vector %d: Failed to decode hex hash: %s", i, err) } c, err := aes.NewCipher(key) if err != nil { t.Fatalf("Test vector %d: Failed to create AES instance: %s", i, err) } h, err := New(c) if err != nil { t.Fatalf("Test vector %d: Failed to create CMac instance: %s", i, err) } _, err = h.Write(msg) if err != nil { t.Fatalf("Test vector %d: CMac write failed: %s", i, err) } sum := h.Sum(nil) if !bytes.Equal(sum, hash) { t.Fatalf("Test vector %d : MAC does not match:\nFound: %v\nExpected: %v", i, hex.EncodeToString(sum), hex.EncodeToString(hash)) } if !Verify(hash, msg, c) { t.Fatalf("Test vector %d: verification of MAC failed", i) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/crypto.go000066400000000000000000000016021520706056300233350ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package crypto contains commen and general useful // cryptographic functions and types. package crypto import "strconv" // A KeySizeError indicates, that the size of a given key // does not match the expected size. type KeySizeError int func (k KeySizeError) Error() string { return "invalid key size " + strconv.Itoa(int(k)) } // A NonceSizeError indicates, that the size of a given nonce // does not match the expected size. type NonceSizeError int func (n NonceSizeError) Error() string { return "invalid nonce size " + strconv.Itoa(int(n)) } // A AuthenticationError indicates, that an authentication // process failed. E.g. the message authentication of a AEAD // cipher. type AuthenticationError struct{} func (a AuthenticationError) Error() string { return "authentication failed" } golang-github-enceve-crypto-0.0~git20160707.34d48bb/dh/000077500000000000000000000000001520706056300220625ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/dh/dh.go000066400000000000000000000060561520706056300230130ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package dh implements the Diffie-Hellman key exchange over // multiplicative groups of integers modulo a prime. // This also defines some commen groups described in RFC 3526. package dh import ( cryptorand "crypto/rand" "errors" "io" "math/big" ) var zero *big.Int = big.NewInt(0) var one *big.Int = big.NewInt(1) var two *big.Int = big.NewInt(2) // IsSafePrime returns true, if the prime of the group is // a so called safe-prime. For a group with a safe-prime prime // number the Decisional-Diffie-Hellman-Problem (DDH) is a // 'hard' problem. The n argument is the number of iterations // for the probabilistic prime test. // It's recommend to use DDH-safe groups for DH-exchanges. func IsSafePrimeGroup(g *Group, n int) bool { q := new(big.Int).Sub(g.P, one) q = q.Div(q, two) return q.ProbablyPrime(n) } // PublicKey is the type of DH public keys. type PublicKey *big.Int // PrivateKey is the type of DH private keys. type PrivateKey *big.Int // Group represents a mathematical group defined // by a large prime and a generator. type Group struct { P *big.Int // The prime G *big.Int // The generator } // GenerateKey generates a public/private key pair using entropy from rand. // If rand is nil, crypto/rand.Reader will be used. func (g *Group) GenerateKey(rand io.Reader) (private PrivateKey, public PublicKey, err error) { if g.P == nil { panic("crypto/dh: group prime is nil") } if g.G == nil { panic("crypto/dh: group generator is nil") } if rand == nil { rand = cryptorand.Reader } // Ensure, that p.G ^ privateKey > than g.P // (only modulo calculations are safe) // The minimal (and common) value for p.G is 2 // So 2 ^ (1 + 'bitsize of p.G') > than g.P min := big.NewInt(int64(g.P.BitLen() + 1)) bytes := make([]byte, (g.P.BitLen()+7)/8) for private == nil { _, err = io.ReadFull(rand, bytes) if err != nil { private = nil return } // Clear bits in the first byte to increase // the probability that the candidate is < g.P. bytes[0] = 0 if private == nil { private = new(big.Int) } (*private).SetBytes(bytes) if (*private).Cmp(min) < 0 { private = nil } } public = new(big.Int).Exp(g.G, private, g.P) return } // PublicKey returns the public key corresponding to the given private one. func (g *Group) PublicKey(private PrivateKey) (public PublicKey) { public = new(big.Int).Exp(g.G, private, g.P) return } //private returns a non-nil error if the given public key is // not a possible element of the group. This means, that the // public key is < 0 or > g.P. func (g *Group) Check(peersPublic PublicKey) (err error) { if !((*peersPublic).Cmp(zero) >= 0 && (*peersPublic).Cmp(g.P) == -1) { err = errors.New("peer's public is not a possible group element") } return } // ComputeSecret returns the secret computed from // the own private and the peer's public key. func (g *Group) ComputeSecret(private PrivateKey, peersPublic PublicKey) (secret *big.Int) { secret = new(big.Int).Exp(peersPublic, private, g.P) return } golang-github-enceve-crypto-0.0~git20160707.34d48bb/dh/dh_test.go000066400000000000000000000037741520706056300240560ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package dh import ( "crypto/rand" "fmt" "testing" ) // A Diffie-Hellman exchange example. func ExampleKeyExchange() { // using 2048 bit group group := RFC3526_2048() // Alice alicePrivate, alicePublic, err := group.GenerateKey(rand.Reader) if err != nil { fmt.Printf("Failed to generate alice's private / public key pair: %s", err) } // Bob bobPrivate, bobPublic, err := group.GenerateKey(rand.Reader) if err != nil { fmt.Printf("Failed to generate bob's private / public key pair: %s", err) } secretAlice := group.ComputeSecret(alicePrivate, bobPublic) secretBob := group.ComputeSecret(bobPrivate, alicePublic) if secretAlice.Cmp(secretBob) != 0 { fmt.Printf("key exchange failed - secrets not equal\nAlice: %v\nBob : %v", secretAlice, secretBob) } fmt.Println("key exchange succeed") // Output: // key exchange succeed } func BenchmarkGenerateKey2048(b *testing.B) { group := RFC3526_2048() for i := 0; i < b.N; i++ { _, _, err := group.GenerateKey(rand.Reader) if err != nil { b.Fatal("Failed to generate private / public key pair") } } } func Benchmark2048(b *testing.B) { group := RFC3526_2048() alicePrivate, _, err := group.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate alice's private / public key: %s", err) } _, bobPublic, err := group.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate bob's private / public key: %s", err) } for i := 0; i < b.N; i++ { group.ComputeSecret(alicePrivate, bobPublic) } } func Benchmark4096(b *testing.B) { group := RFC3526_4096() alicePrivate, _, err := group.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate alice's private / public key: %s", err) } _, bobPublic, err := group.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate bob's private / public key: %s", err) } for i := 0; i < b.N; i++ { group.ComputeSecret(alicePrivate, bobPublic) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/dh/ecdh/000077500000000000000000000000001520706056300227655ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/dh/ecdh/curve25519.go000066400000000000000000000030551520706056300250510ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package ecdh import ( cryptorand "crypto/rand" "errors" "io" "golang.org/x/crypto/curve25519" ) type ecdh25519 struct{} // Curve25519 creates a new ecdh.KeyExchange with // the elliptic curve Curve25519. func Curve25519() KeyExchange { return ecdh25519{} } func (c ecdh25519) GenerateKey(rand io.Reader) (private PrivateKey, public PublicKey, err error) { if rand == nil { rand = cryptorand.Reader } var pri, pub [32]byte _, err = io.ReadFull(rand, pri[:]) if err != nil { return } // From https://cr.yp.to/ecdh.html pri[0] &= 248 pri[31] &= 127 pri[31] |= 64 curve25519.ScalarBaseMult(&pub, &pri) private = pri[:] public = pub[:] return } func (c ecdh25519) PublicKey(private PrivateKey) (public PublicKey) { if len(private) != 32 { panic("ecdh: private key is not 32 byte") } var pri, pub [32]byte copy(pri[:], private) curve25519.ScalarBaseMult(&pub, &pri) public = pub[:] return } func (c ecdh25519) Check(peersPublic PublicKey) (err error) { if len(peersPublic) != 32 { err = errors.New("peers public key is not 32 byte") } return } func (c ecdh25519) ComputeSecret(private PrivateKey, peersPublic PublicKey) (secret []byte) { if len(private) != 32 { panic("ecdh: private key is not 32 byte") } if len(peersPublic) != 32 { panic("ecdh: peers public key is not 32 byte") } var sec, pri, pub [32]byte copy(pri[:], private) copy(pub[:], peersPublic) curve25519.ScalarMult(&sec, &pri, &pub) secret = sec[:] return } golang-github-enceve-crypto-0.0~git20160707.34d48bb/dh/ecdh/ecdh.go000066400000000000000000000030601520706056300242160ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package ecdh implements the Diffie-Hellman key exchange // with elliptic curves. This package directly implements // generic curves imlementing elliptic.Curve // (the NIST curves P224, P256, P384 and P521) // and Bernstein's Curve25519. Other curves can be used // by implementing the KeyExchange interface. // // For generic curves this implementation of ECDH // only uses the x-coordinate as the computed secret. package ecdh import "io" // PublicKey is the type of ECDH public keys. type PublicKey []byte // PrivateKey is the type of ECDH private keys. type PrivateKey []byte // KeyExchange is the interface defining all functions // necessary for ECDH. type KeyExchange interface { // GenerateKey generates a private/public key pair using entropy from rand. // If rand is nil, crypto/rand.Reader will be used. GenerateKey(rand io.Reader) (private PrivateKey, public PublicKey, err error) // PublicKey returns the public key corresponding to the given private one. PublicKey(private PrivateKey) (public PublicKey) // Check returns a non-nil error if the peers public key cannot used for the // key exchange (e.g. the public key isn't a point of the elliptic curve) // It's recommended to check peer's public key before computing the secret. Check(peersPublic PublicKey) (err error) // ComputeSecret returns the secret value computed from the given private key // and the peers public key. ComputeSecret(private PrivateKey, peersPublic PublicKey) (secret []byte) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/dh/ecdh/ecdh_test.go000066400000000000000000000103571520706056300252640ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package ecdh import ( "bytes" "crypto/elliptic" "crypto/rand" "fmt" "testing" ) // An example for the ECDH key-exchange using the curve P256. func ExampleGenericKeyExchange() { p256 := GenericCurve(elliptic.P256()) privateAlice, publicAlice, err := p256.GenerateKey(rand.Reader) if err != nil { fmt.Printf("Failed to generate Alice's private/public key pair: %s\n", err) } privateBob, publicBob, err := p256.GenerateKey(rand.Reader) if err != nil { fmt.Printf("Failed to generate Bob's private/public key pair: %s\n", err) } if err := p256.Check(publicBob); err != nil { fmt.Printf("Bob's public key is not on the curve: %s\n", err) } secretAlice := p256.ComputeSecret(privateAlice, publicBob) if err := p256.Check(publicAlice); err != nil { fmt.Printf("Alice's public key is not on the curve: %s\n", err) } secretBob := p256.ComputeSecret(privateBob, publicAlice) if !bytes.Equal(secretAlice, secretBob) { fmt.Printf("key exchange failed - secret X coordinates not equal\n") } fmt.Println("\nkey exchange succeed\n") // Output: // key exchange succeed } // An example for the ECDH key-exchange using Curve25519. func ExampleCurve25519KeyExchange() { c25519 := Curve25519() privateAlice, publicAlice, err := c25519.GenerateKey(rand.Reader) if err != nil { fmt.Printf("Failed to generate Alice's private/public key pair: %s\n", err) } privateBob, publicBob, err := c25519.GenerateKey(rand.Reader) if err != nil { fmt.Printf("Failed to generate Bob's private/public key pair: %s\n", err) } if err := c25519.Check(publicBob); err != nil { fmt.Printf("Bob's public key is not on the curve: %s\n", err) } secretAlice := c25519.ComputeSecret(privateAlice, publicBob) if err := c25519.Check(publicAlice); err != nil { fmt.Printf("Alice's public key is not on the curve: %s\n", err) } secretBob := c25519.ComputeSecret(privateBob, publicAlice) if !bytes.Equal(secretAlice, secretBob) { fmt.Printf("key exchange failed - secret X coordinates not equal\n") } fmt.Println("\nkey exchange succeed\n") // Output: // key exchange succeed } func BenchmarkCurve25519(b *testing.B) { curve := Curve25519() privateAlice, _, err := curve.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) } _, publicBob, err := curve.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate Bob's private/public key pair: %s", err) } for i := 0; i < b.N; i++ { curve.ComputeSecret(privateAlice, publicBob) } } func BenchmarkKeyGenerateCurve25519(b *testing.B) { curve := Curve25519() for i := 0; i < b.N; i++ { _, _, err := curve.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) } } } func BenchmarkP256(b *testing.B) { p256 := GenericCurve(elliptic.P256()) privateAlice, _, err := p256.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) } _, publicBob, err := p256.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate Bob's private/public key pair: %s", err) } b.ResetTimer() for i := 0; i < b.N; i++ { p256.ComputeSecret(privateAlice, publicBob) } } func BenchmarkKeyGenerateP256(b *testing.B) { p256 := GenericCurve(elliptic.P256()) for i := 0; i < b.N; i++ { _, _, err := p256.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) } } } func BenchmarkP521(b *testing.B) { p521 := GenericCurve(elliptic.P256()) privateAlice, _, err := p521.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) } _, publicBob, err := p521.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate Bob's private/public key pair: %s", err) } b.ResetTimer() for i := 0; i < b.N; i++ { p521.ComputeSecret(privateAlice, publicBob) } } func BenchmarkKeyGenerateP521(b *testing.B) { p521 := GenericCurve(elliptic.P256()) for i := 0; i < b.N; i++ { _, _, err := p521.GenerateKey(rand.Reader) if err != nil { b.Fatalf("Failed to generate Alice's private/public key pair: %s", err) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/dh/ecdh/generic.go000066400000000000000000000035701520706056300247350ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package ecdh import ( "crypto/elliptic" cryptorand "crypto/rand" "errors" "io" "math/big" ) // The same unmarshal as elliptic.Unmarshal but without // point checking (see Check method) func unmarshal(curve elliptic.Curve, data []byte) (x, y *big.Int) { byteLen := (curve.Params().BitSize + 7) >> 3 if len(data) != 1+2*byteLen { return } if data[0] != 4 { // uncompressed form return } x = new(big.Int).SetBytes(data[1 : 1+byteLen]) y = new(big.Int).SetBytes(data[1+byteLen:]) return } // GenericCurve creates a new ecdh.KeyExchange with // generic elliptic.Curve implementations. func GenericCurve(c elliptic.Curve) KeyExchange { if c == nil { panic("ecdh: curve is nil") } return genericCurve{curve: c} } type genericCurve struct { curve elliptic.Curve } func (g genericCurve) GenerateKey(rand io.Reader) (private PrivateKey, public PublicKey, err error) { if rand == nil { rand = cryptorand.Reader } private, x, y, err := elliptic.GenerateKey(g.curve, rand) if err != nil { private = nil return } public = elliptic.Marshal(g.curve, x, y) return } func (g genericCurve) PublicKey(private PrivateKey) (public PublicKey) { N := g.curve.Params().N if new(big.Int).SetBytes(private).Cmp(N) >= 0 { panic("ecdh: private key cannot used with given curve") } x, y := g.curve.ScalarBaseMult(private) public = elliptic.Marshal(g.curve, x, y) return } func (g genericCurve) Check(peersPublic PublicKey) (err error) { x, y := unmarshal(g.curve, peersPublic) if !g.curve.IsOnCurve(x, y) { err = errors.New("peer's public key is not on curve") } return } func (g genericCurve) ComputeSecret(private PrivateKey, peersPublic PublicKey) (secret []byte) { x, y := unmarshal(g.curve, peersPublic) sX, _ := g.curve.ScalarMult(x, y, private) secret = sX.Bytes() return } golang-github-enceve-crypto-0.0~git20160707.34d48bb/dh/groups.go000066400000000000000000000110211520706056300237230ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package dh import ( "math/big" "sync" ) // DH groups defined in https://www.ietf.org/rfc/rfc3526.txt const ( // The 2048 bit prime form 3. rfc3526_2048G = "02" rfc3526_2048P = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3" + "404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BF" + "B5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C6" + "2F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28" + "FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF" // The 3072 bit prime form 4. rfc3526_3072G = "02" rfc3526_3072P = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3" + "404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BF" + "B5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C6" + "2F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28" + "FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1" + "CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA0" + "6D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B8" + "2D120A93AD2CAFFFFFFFFFFFFFFFF" // The 4096 bit prime form 5. rfc3526_4096G = "02" rfc3526_4096P = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3" + "404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BF" + "B5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C6" + "2F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28" + "FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1" + "CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA0" + "6D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B8" + "2D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF" + "92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B" + "05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF" ) var once sync.Once var rfc3526_2048 *Group var rfc3526_3072 *Group var rfc3526_4096 *Group func initRFC3526_2048() { rfc3526_2048 = &Group{} rfc3526_2048.G, _ = new(big.Int).SetString(rfc3526_2048G, 16) rfc3526_2048.P, _ = new(big.Int).SetString(rfc3526_2048P, 16) } func initRFC3526_3072() { rfc3526_3072 = &Group{} rfc3526_3072.G, _ = new(big.Int).SetString(rfc3526_3072G, 16) rfc3526_3072.P, _ = new(big.Int).SetString(rfc3526_3072P, 16) } func initRFC3526_4096() { rfc3526_4096 = &Group{} rfc3526_4096.G, _ = new(big.Int).SetString(rfc3526_4096G, 16) rfc3526_4096.P, _ = new(big.Int).SetString(rfc3526_4096P, 16) } // Initialize the primes and generators func initAll() { initRFC3526_2048() initRFC3526_3072() initRFC3526_4096() } // RFC3526_2048 creates a new dh.Group consisting of the prime // and the generator. The prime (and generator) are // described in RFC 3526 (3.). The prime is a 2048 bit value. func RFC3526_2048() *Group { once.Do(initAll) g := &Group{ P: new(big.Int).Set(rfc3526_2048.P), G: new(big.Int).Set(rfc3526_2048.G), } return g } // RFC3526_3072 creates a new dh.Group consisting of the prime // and the generator. The prime (and generator) are // described in RFC 3526 (4.). The prime is a 3072 bit value. func RFC3526_3072() *Group { once.Do(initAll) g := &Group{ P: new(big.Int).Set(rfc3526_3072.P), G: new(big.Int).Set(rfc3526_3072.G), } return g } // RFC3526_4096 creates a new dh.Group consisting of the prime // and the generator. The prime (and generator) are // described in RFC 3526 (5.). The prime is a 4096 bit value. func RFC3526_4096() *Group { once.Do(initAll) g := &Group{ P: new(big.Int).Set(rfc3526_4096.P), G: new(big.Int).Set(rfc3526_4096.G), } return g } golang-github-enceve-crypto-0.0~git20160707.34d48bb/hc128/000077500000000000000000000000001520706056300223145ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/hc128/hc128.go000066400000000000000000000060431520706056300234730ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package hc128 implements the stream cipher // HC-128 from the eSTREAM portfolio (software) // designed by Hongjun Wu. package hc128 // import "github.com/enceve/crypto/hc128" import "crypto/cipher" const ( mod512 uint32 = 0x1FF mod1024 uint32 = 0x3FF ) // NewCipher returns a new cipher.Stream implementing the // HC-128 cipher with the given key and nonce. func NewCipher(nonce, key *[16]byte) cipher.Stream { c := new(streamCipher) initialize(nonce, key, &(c.p), &(c.q)) return c } type streamCipher struct { p, q [512]uint32 ctr uint32 keyStream [4]byte off int } func initialize(nonce, key *[16]byte, p, q *[512]uint32) { var tmp [1280]uint32 tmp[0] = uint32(key[0]) | (uint32(key[1]) << 8) | (uint32(key[2]) << 16) | (uint32(key[3]) << 24) tmp[1] = uint32(key[4]) | (uint32(key[5]) << 8) | (uint32(key[6]) << 16) | (uint32(key[7]) << 24) tmp[2] = uint32(key[8]) | (uint32(key[9]) << 8) | (uint32(key[10]) << 16) | (uint32(key[11]) << 24) tmp[3] = uint32(key[12]) | (uint32(key[13]) << 8) | (uint32(key[14]) << 16) | (uint32(key[15]) << 24) copy(tmp[4:8], tmp[0:4]) tmp[8] = uint32(nonce[0]) | (uint32(nonce[1]) << 8) | (uint32(nonce[2]) << 16) | (uint32(nonce[3]) << 24) tmp[9] = uint32(nonce[4]) | (uint32(nonce[5]) << 8) | (uint32(nonce[6]) << 16) | (uint32(nonce[7]) << 24) tmp[10] = uint32(nonce[8]) | (uint32(nonce[9]) << 8) | (uint32(nonce[10]) << 16) | (uint32(nonce[11]) << 24) tmp[11] = uint32(nonce[12]) | (uint32(nonce[13]) << 8) | (uint32(nonce[14]) << 16) | (uint32(nonce[15]) << 24) copy(tmp[12:16], tmp[8:12]) // expand key and nonce with the f1 and f2 functions // (2.2 http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf) var f2, f1 uint32 for i := 16; i < 1280; i++ { f1, f2 = tmp[i-15], tmp[i-2] f1 = ((f1 >> 7) | (f1 << 25)) ^ ((f1 >> 18) | (f1 << 14)) ^ (f1 >> 3) f2 = ((f2 >> 17) | (f2 << 15)) ^ ((f2 >> 19) | (f2 << 13)) ^ (f2 >> 10) tmp[i] = f1 + f2 + tmp[i-7] + tmp[i-16] + uint32(i) } copy(p[:], tmp[256:(256+512)]) copy(q[:], tmp[768:(768+512)]) // do 1024 iterations for initialization var ctr uint32 for i := range p { p[i] = genKeyStream(&ctr, p, q) } for i := range q { q[i] = genKeyStream(&ctr, p, q) } } func genKeyStream(counter *uint32, p, q *[512]uint32) uint32 { var r, t0, t1, t2, t3 uint32 ctr := *counter j := ctr & mod512 if ctr < 512 { t0 = p[(j-3)&mod512] t1 = p[(j-10)&mod512] t2 = p[(j-511)&mod512] t3 = p[(j-12)&mod512] t0 = ((t0 >> 10) | (t0 << 22)) t1 = ((t1 >> 8) | (t1 << 24)) t2 = ((t2 >> 23) | (t2 << 9)) p[j] += (t0 ^ t2) + t1 t0 = t3 & 0xff t1 = 256 + (t3>>16)&0xff r = (q[t0] + q[t1]) ^ p[j] } else { t0 = q[(j-3)&mod512] t1 = q[(j-10)&mod512] t2 = q[(j-511)&mod512] t3 = q[(j-12)&mod512] t0 = ((t0 << 10) | (t0 >> 22)) t1 = ((t1 << 8) | (t1 >> 24)) t2 = ((t2 << 23) | (t2 >> 9)) q[j] += (t0 ^ t2) + t1 t0 = t3 & 0xff t1 = 256 + (t3>>16)&0xff r = p[t0] + p[t1] ^ q[j] } *counter = (ctr + 1) & mod1024 return r } golang-github-enceve-crypto-0.0~git20160707.34d48bb/hc128/hc128_ref.go000066400000000000000000000020371520706056300243260ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package hc128 import "github.com/enceve/crypto" func (c *streamCipher) XORKeyStream(dst, src []byte) { length := len(src) if len(dst) < length { panic("dst buffer is to small") } if c.off > 0 { left := 4 - c.off if left > length { left = length } for i, v := range c.keyStream[c.off : c.off+left] { dst[i] = src[i] ^ v } src = src[left:] dst = dst[left:] length -= left c.off += left if c.off == 4 { c.off = 0 } } n := length - (length % 4) for i := 0; i < n; i += 4 { k := genKeyStream(&(c.ctr), &(c.p), &(c.q)) dst[i] = src[i] ^ byte(k) dst[i+1] = src[i+1] ^ byte(k>>8) dst[i+2] = src[i+2] ^ byte(k>>16) dst[i+3] = src[i+3] ^ byte(k>>24) } length -= n if length > 0 { k := genKeyStream(&(c.ctr), &(c.p), &(c.q)) c.keyStream[0] = byte(k) c.keyStream[1] = byte(k >> 8) c.keyStream[2] = byte(k >> 16) c.keyStream[3] = byte(k >> 24) c.off += crypto.XOR(dst[n:], src[n:], c.keyStream[:]) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/hc128/hc128_test.go000066400000000000000000000030171520706056300245300ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package hc128 import ( "bytes" "encoding/hex" "testing" ) func TestXORKeyStream(t *testing.T) { var nonce, key [16]byte c := NewCipher(&nonce, &key) ref := NewCipher(&nonce, &key) dst, src := make([]byte, 32), make([]byte, 16) cmp := make([]byte, 32) c.XORKeyStream(dst, src[:2]) c.XORKeyStream(dst[2:], src[:1]) c.XORKeyStream(dst[3:], src) c.XORKeyStream(dst[19:], src[:13]) ref.XORKeyStream(cmp, cmp) if !bytes.Equal(dst, cmp) { t.Fatalf("XORKeyStream failed:\nFound: %s\nExpected: %s", hex.EncodeToString(dst), hex.EncodeToString(cmp)) } dst, src = make([]byte, 15), make([]byte, 16) func() { defer func() { if err := recover(); err == nil { t.Fatal("Recover expected error, but no one occured") } }() c.XORKeyStream(dst, src) }() } // Benchmarks func BenchmarkXORKeyStream_64B(b *testing.B) { var nonce, key [16]byte c := NewCipher(&nonce, &key) buf := make([]byte, 64) b.SetBytes(int64(len(buf))) for i := 0; i < b.N; i++ { c.XORKeyStream(buf, buf) } } func BenchmarkXORKeyStream_1K(b *testing.B) { var nonce, key [16]byte c := NewCipher(&nonce, &key) buf := make([]byte, 1024) b.SetBytes(int64(len(buf))) for i := 0; i < b.N; i++ { c.XORKeyStream(buf, buf) } } func BenchmarkXORKeyStream_64K(b *testing.B) { var nonce, key [16]byte c := NewCipher(&nonce, &key) buf := make([]byte, 64*1024) b.SetBytes(int64(len(buf))) for i := 0; i < b.N; i++ { c.XORKeyStream(buf, buf) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/hc128/vectors_test.go000066400000000000000000000033661520706056300253770ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package hc128 import ( "bytes" "encoding/hex" "testing" ) // Test vectors from the HC128 description by Hongjun Wu. // http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf // The byte order was changed: 0x73150082 -> 0x82001573 var vectors128 = []struct { key, nonce, keystream string }{ { key: "00000000000000000000000000000000", nonce: "00000000000000000000000000000000", keystream: "82001573a003fd3b7fd72ffb0eaf63aac62f12deb629dca72785a66268ec758b", }, { key: "00000000000000000000000000000000", nonce: "01000000000000000000000000000000", keystream: "d59318c058e9dbb798ec658f046617642467fc36ec6e2cc8a7381c1b952ab4c9", }, { key: "55000000000000000000000000000000", nonce: "00000000000000000000000000000000", keystream: "a45182510a93b40431f92ab032f039067aa4b4bc0b482257729ff92b66e5c0cd", }, } func TestVectors(t *testing.T) { for i, v := range vectors128 { key, err := hex.DecodeString(v.key) if err != nil { t.Fatalf("Test vector %d: Failed to decode hex key: %s", i, err) } nonce, err := hex.DecodeString(v.nonce) if err != nil { t.Fatalf("Test vector %d: Failed to decode hex nonce: %s", i, err) } keystream, err := hex.DecodeString(v.keystream) if err != nil { t.Fatalf("Test vector %d: Failed to decode hex keystream: %s", i, err) } var Key, Nonce [16]byte copy(Key[:], key) copy(Nonce[:], nonce) c := NewCipher(&Nonce, &Key) buf := make([]byte, len(keystream)) c.XORKeyStream(buf, buf) if !bytes.Equal(buf, keystream) { t.Fatalf("Test vector %d: Unexpected keystream:\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(keystream)) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/hc256/000077500000000000000000000000001520706056300223165ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/hc256/hc256.go000066400000000000000000000076611520706056300235060ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package hc256 implements the stream cipher // HC-256 designed by Hongjun Wu. package hc256 // import "github.com/enceve/crypto/hc256" import "crypto/cipher" const ( mod1024 uint32 = 0x3FF mod2048 uint32 = 0x7FF ) // NewCipher returns a new cipher.Stream implementing the // HC-256 cipher with the given key and nonce. func NewCipher(nonce, key *[32]byte) cipher.Stream { c := new(streamCipher) initialize(nonce, key, &(c.p), &(c.q)) return c } type streamCipher struct { p, q [1024]uint32 ctr uint32 keyStream [4]byte off int } func initialize(nonce, key *[32]byte, p, q *[1024]uint32) { var tmp [2560]uint32 tmp[0] = uint32(key[0]) | (uint32(key[1]) << 8) | (uint32(key[2]) << 16) | (uint32(key[3]) << 24) tmp[1] = uint32(key[4]) | (uint32(key[5]) << 8) | (uint32(key[6]) << 16) | (uint32(key[7]) << 24) tmp[2] = uint32(key[8]) | (uint32(key[9]) << 8) | (uint32(key[10]) << 16) | (uint32(key[11]) << 24) tmp[3] = uint32(key[12]) | (uint32(key[13]) << 8) | (uint32(key[14]) << 16) | (uint32(key[15]) << 24) tmp[4] = uint32(key[16]) | (uint32(key[17]) << 8) | (uint32(key[18]) << 16) | (uint32(key[19]) << 24) tmp[5] = uint32(key[20]) | (uint32(key[21]) << 8) | (uint32(key[22]) << 16) | (uint32(key[23]) << 24) tmp[6] = uint32(key[24]) | (uint32(key[25]) << 8) | (uint32(key[26]) << 16) | (uint32(key[27]) << 24) tmp[7] = uint32(key[28]) | (uint32(key[29]) << 8) | (uint32(key[30]) << 16) | (uint32(key[31]) << 24) tmp[8] = uint32(nonce[0]) | (uint32(nonce[1]) << 8) | (uint32(nonce[2]) << 16) | (uint32(nonce[3]) << 24) tmp[9] = uint32(nonce[4]) | (uint32(nonce[5]) << 8) | (uint32(nonce[6]) << 16) | (uint32(nonce[7]) << 24) tmp[10] = uint32(nonce[8]) | (uint32(nonce[9]) << 8) | (uint32(nonce[10]) << 16) | (uint32(nonce[11]) << 24) tmp[11] = uint32(nonce[12]) | (uint32(nonce[13]) << 8) | (uint32(nonce[14]) << 16) | (uint32(nonce[15]) << 24) tmp[12] = uint32(nonce[16]) | (uint32(nonce[17]) << 8) | (uint32(nonce[18]) << 16) | (uint32(nonce[19]) << 24) tmp[13] = uint32(nonce[20]) | (uint32(nonce[21]) << 8) | (uint32(nonce[22]) << 16) | (uint32(nonce[23]) << 24) tmp[14] = uint32(nonce[24]) | (uint32(nonce[25]) << 8) | (uint32(nonce[26]) << 16) | (uint32(nonce[27]) << 24) tmp[15] = uint32(nonce[28]) | (uint32(nonce[29]) << 8) | (uint32(nonce[30]) << 16) | (uint32(nonce[31]) << 24) // expand key and nonce with the f1 and f2 functions // (2.2 https://eprint.iacr.org/2004/092.pdf) var f2, f1 uint32 for i := 16; i < 2560; i++ { f1, f2 = tmp[i-15], tmp[i-2] f1 = ((f1 >> 7) | (f1 << 25)) ^ ((f1 >> 18) | (f1 << 14)) ^ (f1 >> 3) f2 = ((f2 >> 17) | (f2 << 15)) ^ ((f2 >> 19) | (f2 << 13)) ^ (f2 >> 10) tmp[i] = f1 + f2 + tmp[i-7] + tmp[i-16] + uint32(i) } copy(p[:], tmp[512:(512+1024)]) copy(q[:], tmp[1536:(1536+1024)]) // do 4096 iterations for initialization var ctr uint32 for i := 0; i < 4096; i++ { genKeyStream(&ctr, p, q) } } func genKeyStream(counter *uint32, p, q *[1024]uint32) uint32 { var r, t0, t1, t2, t3 uint32 ctr := *counter j := ctr & mod1024 if ctr < 1024 { t0 = p[(j-3)&mod1024] t1 = p[(j-1023)&mod1024] t2 = t0 ^ t1 t0 = (t0 >> 10) | (t0 << 22) t1 = (t1 >> 23) | (t1 << 9) t3 = t0 ^ t1 t0 = p[(j-10)&mod1024] t1 = q[t2&mod1024] p[j] += t0 + t1 + t3 t3 = p[(j-12)&mod1024] t0 = 256 + ((t3 >> 8) & 0xff) t1 = 512 + ((t3 >> 16) & 0xff) t2 = 768 + ((t3 >> 24) & 0xff) t3 = t3 & 0xff r = q[t3] + q[t0] + q[t1] + q[t2] ^ p[j] } else { t0 = q[(j-3)&mod1024] t1 = q[(j-1023)&mod1024] t2 = t0 ^ t1 t0 = (t0 >> 10) | (t0 << 22) t1 = (t1 >> 23) | (t1 << 9) t3 = t0 ^ t1 t0 = q[(j-10)&mod1024] t1 = p[t2&mod1024] q[j] += t0 + t1 + t3 t3 = q[(j-12)&mod1024] t0 = 256 + ((t3 >> 8) & 0xff) t1 = 512 + ((t3 >> 16) & 0xff) t2 = 768 + ((t3 >> 24) & 0xff) t3 = t3 & 0xff r = p[t3] + p[t0] + p[t1] + p[t2] ^ q[j] } *counter = (ctr + 1) & mod2048 return r } golang-github-enceve-crypto-0.0~git20160707.34d48bb/hc256/hc256_ref.go000066400000000000000000000017001520706056300243260ustar00rootroot00000000000000package hc256 import "github.com/enceve/crypto" func (c *streamCipher) XORKeyStream(dst, src []byte) { length := len(src) if len(dst) < length { panic("dst buffer is to small") } if c.off > 0 { left := 4 - c.off if left > length { left = length } for i, v := range c.keyStream[c.off : c.off+left] { dst[i] = src[i] ^ v } src = src[left:] dst = dst[left:] length -= left c.off += left if c.off == 4 { c.off = 0 } } n := length - (length % 4) for i := 0; i < n; i += 4 { k := genKeyStream(&(c.ctr), &(c.p), &(c.q)) dst[i] = src[i] ^ byte(k) dst[i+1] = src[i+1] ^ byte(k>>8) dst[i+2] = src[i+2] ^ byte(k>>16) dst[i+3] = src[i+3] ^ byte(k>>24) } length -= n if length > 0 { k := genKeyStream(&(c.ctr), &(c.p), &(c.q)) c.keyStream[0] = byte(k) c.keyStream[1] = byte(k >> 8) c.keyStream[2] = byte(k >> 16) c.keyStream[3] = byte(k >> 24) c.off += crypto.XOR(dst[n:], src[n:], c.keyStream[:]) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/hc256/hc256_test.go000066400000000000000000000030171520706056300245340ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package hc256 import ( "bytes" "encoding/hex" "testing" ) func TestXORKeyStream(t *testing.T) { var nonce, key [32]byte c := NewCipher(&nonce, &key) ref := NewCipher(&nonce, &key) dst, src := make([]byte, 32), make([]byte, 16) cmp := make([]byte, 32) c.XORKeyStream(dst, src[:2]) c.XORKeyStream(dst[2:], src[:1]) c.XORKeyStream(dst[3:], src) c.XORKeyStream(dst[19:], src[:13]) ref.XORKeyStream(cmp, cmp) if !bytes.Equal(dst, cmp) { t.Fatalf("XORKeyStream failed:\nFound: %s\nExpected: %s", hex.EncodeToString(dst), hex.EncodeToString(cmp)) } dst, src = make([]byte, 15), make([]byte, 16) func() { defer func() { if err := recover(); err == nil { t.Fatal("Recover expected error, but no one occured") } }() c.XORKeyStream(dst, src) }() } // Benchmarks func BenchmarkXORKeyStream_64B(b *testing.B) { var nonce, key [32]byte c := NewCipher(&nonce, &key) buf := make([]byte, 64) b.SetBytes(int64(len(buf))) for i := 0; i < b.N; i++ { c.XORKeyStream(buf, buf) } } func BenchmarkXORKeyStream_1K(b *testing.B) { var nonce, key [32]byte c := NewCipher(&nonce, &key) buf := make([]byte, 1024) b.SetBytes(int64(len(buf))) for i := 0; i < b.N; i++ { c.XORKeyStream(buf, buf) } } func BenchmarkXORKeyStream_64K(b *testing.B) { var nonce, key [32]byte c := NewCipher(&nonce, &key) buf := make([]byte, 64*1024) b.SetBytes(int64(len(buf))) for i := 0; i < b.N; i++ { c.XORKeyStream(buf, buf) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/hc256/vectors_test.go000066400000000000000000000035121520706056300253720ustar00rootroot00000000000000package hc256 import ( "bytes" "encoding/hex" "testing" ) // Test vectors taken from the HC256 description by Hongjun Wu // https://eprint.iacr.org/2004/092.pdf // The byte order was changed: // 0x8589075b -> 0x5b078985 var vectors256 = []struct { key, nonce, keystream string }{ { key: "0000000000000000000000000000000000000000000000000000000000000000", nonce: "0000000000000000000000000000000000000000000000000000000000000000", keystream: "5b078985d8f6f30d42c5c02fa6b6795153f06534801f89f24e74248b720b4818", }, { key: "0000000000000000000000000000000000000000000000000000000000000000", nonce: "0100000000000000000000000000000000000000000000000000000000000000", keystream: "afe2a2bf4f17cee9fec2058bd1b18bb15fc042ee712b3101dd501fc60b082a50", }, { key: "5500000000000000000000000000000000000000000000000000000000000000", nonce: "0000000000000000000000000000000000000000000000000000000000000000", keystream: "1c404afe4fe25fed958f9ad1ae36c06f88a65a3cc0abe223aeb3902f420ed3a8", }, } func TestVectors(t *testing.T) { for i, v := range vectors256 { key, err := hex.DecodeString(v.key) if err != nil { t.Fatalf("Test vector %d: Failed to decode hex key: %s", i, err) } nonce, err := hex.DecodeString(v.nonce) if err != nil { t.Fatalf("Test vector %d: Failed to decode hex nonce: %s", i, err) } keystream, err := hex.DecodeString(v.keystream) if err != nil { t.Fatalf("Test vector %d: Failed to decode hex keystream: %s", i, err) } var Key, Nonce [32]byte copy(Key[:], key) copy(Nonce[:], nonce) c := NewCipher(&Nonce, &Key) buf := make([]byte, len(keystream)) c.XORKeyStream(buf, buf) if !bytes.Equal(buf, keystream) { t.Fatalf("Test vector %d: Unexpected keystream:\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(keystream)) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/pad/000077500000000000000000000000001520706056300222335ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/pad/iso10126.go000066400000000000000000000022541520706056300237510ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package pad import ( "io" ) type isoPadding struct { blocksize int random io.Reader } func (p *isoPadding) BlockSize() int { return p.blocksize } func (p *isoPadding) Overhead(src []byte) int { return overhead(p.blocksize, src) } func (p *isoPadding) Pad(src []byte) []byte { overhead := p.Overhead(src) dst := make([]byte, overhead) n, e := io.ReadFull(p.random, dst) if e != nil || n != overhead { // if random fails, do a pkcs7 padding for i := range dst { dst[i] = byte(overhead) } } dst[overhead-1] = byte(overhead) return append(src, dst...) } func (p *isoPadding) Unpad(src []byte) ([]byte, error) { length := len(src) if length == 0 || length%p.blocksize != 0 { return nil, notMulOfBlockErr } block := src[length-p.blocksize:] unLen, err := verifyISO(block, p.blocksize) if err != nil { return nil, err } return src[:(length - p.BlockSize() + unLen)], nil } func verifyISO(block []byte, length int) (p int, err error) { padLen := block[length-1] if padLen == 0 || int(padLen) > length { err = badPadErr } p = length - int(padLen) return } golang-github-enceve-crypto-0.0~git20160707.34d48bb/pad/pad.go000066400000000000000000000051031520706056300233250ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package pad implements some padding schemes // for block ciphers. package pad import ( cryptorand "crypto/rand" "errors" "io" ) var badPadErr = errors.New("bad padding bytes") var notMulOfBlockErr = errors.New("src is not a multiply of the padding blocksize") // The Padding interface represents a padding scheme. type Padding interface { // BlockSize returns the block size of the padding. BlockSize() int // Returns the overhead, the padding will cause // by padding the given byte slice. The overhead // will always be between 1 and BlockSize() inclusively. Overhead(src []byte) int // Pads the last (may incomplete) block of the src slice // to a padded and complete block, appends the padding bytes // to the src slice and returns this slice. // The length of the returned slice is len(src) + Overhead(src) Pad(src []byte) []byte // Takes a slice and tries to remove the padding bytes // form the last block. Therefore the length of the // src argument must be a multiply of the blocksize. // If the returned error is nil, the padding could be // removed successfully. The returned slice holds the // unpadded src bytes. Unpad(src []byte) ([]byte, error) } // NewX923 returns a new pad.Padding implementing the ANSI X.923 scheme. // Only block sizes between 1 and 255 are valid. func NewX923(blocksize int) Padding { if blocksize < 1 || blocksize > 255 { panic("illegal blocksize - size must between 0 and 256") } pad := x923Padding(blocksize) return pad } // NewPKCS7 returns a new pad.Padding implementing the PKCS 7 scheme. // Only block sizes between 1 and 255 are valid. func NewPKCS7(blocksize int) Padding { if blocksize < 1 || blocksize > 255 { panic("illegal blocksize - size must between 0 and 256") } pad := pkcs7Padding(blocksize) return pad } // NewISO10126 returns a new pad.Padding, which uses the padding scheme // described in ISO 10126. The padding bytes are taken // form the given rand argument. If rand is nil, crypto/rand will be used. // Only block sizes between 1 and 255 are valid. func NewISO10126(blocksize int, rand io.Reader) Padding { if blocksize < 1 || blocksize > 255 { panic("illegal blocksize - size must between 0 and 256") } pad := new(isoPadding) pad.blocksize = blocksize if rand == nil { pad.random = cryptorand.Reader } else { pad.random = rand } return pad } // Returns the overhead for a given slice with a // specific block size. func overhead(blocksize int, src []byte) int { return blocksize - (len(src) % blocksize) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/pad/pad_test.go000066400000000000000000000144431520706056300243730ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package pad import ( "bytes" "crypto/rand" "strconv" "testing" ) var blocksizes = [5]int{8, 16, 32, 64, 128} var msglengths = [8]int{0, 1, 8, 16, 32, 64, 128, 249} func generateSequence(out []byte, seed uint32) { a := 0xDEAD4BAD * seed // prime b := uint32(1) for i := range out { // fill the buf t := a + b a = b b = t out[i] = byte(t >> 24) } } func TestPKCS7(t *testing.T) { message := make([]byte, 249) for i, b := range blocksizes { for j, m := range msglengths { msg := message[:m] generateSequence(msg, uint32((m+b)*i)) pkcs7 := NewPKCS7(b) pad := pkcs7.Pad(msg) if expected := len(msg) + pkcs7.Overhead(msg); expected != len(pad) { t.Fatalf("Block: %d Message: %d\nOverhead failed: Found: %d Expected: %d", i, j, len(pad), expected) } if len(pad)%b != 0 { t.Fatalf("Block: %d Message: %d\nPadded block not a multiply of blocksize %d", i, j, len(pad)) } unpad, err := pkcs7.Unpad(pad) if err != nil { t.Fatalf("Block: %d Message: %d\nUnpad failed: %s", i, j, err) } if !bytes.Equal(msg, unpad) { t.Fatalf("Block: %d Message: %d\nUnpad does not produces orginal msg", i, j) } padBytes := pad[len(msg):] for _, v := range padBytes { if int(v) != len(pad)-len(msg) { t.Fatalf("Block: %d Message: %d\nPKCS7 does not use PKCS7-Padding scheme", i, j) } } } } } func TestX923(t *testing.T) { message := make([]byte, 249) for i, b := range blocksizes { for j, m := range msglengths { msg := message[:m] generateSequence(msg, uint32((m+b)*i)) x923 := NewX923(b) pad := x923.Pad(msg) if expected := len(msg) + x923.Overhead(msg); expected != len(pad) { t.Fatalf("Block: %d Message: %d\nOverhead failed: Found: %d Expected: %d", i, j, len(pad), expected) } if len(pad)%b != 0 { t.Fatalf("Block: %d Message: %d\nPadded block not a multiply of blocksize %d", i, j, len(pad)) } unpad, err := x923.Unpad(pad) if err != nil { t.Fatalf("Block: %d Message: %d\nUnpad failed: %s", i, j, err) } if !bytes.Equal(msg, unpad) { t.Fatalf("Block: %d Message: %d\nUnpad does not produces orginal msg", i, j) } padBytes := pad[len(msg) : len(pad)-1] for _, v := range padBytes { if int(v) != 0 { t.Fatalf("Block: %d Message: %d\nX923 does not use X923-Padding scheme", i, j) } } if int(pad[len(pad)-1]) != len(pad)-len(msg) { t.Fatalf("Block: %d Message: %d\nX923 does not use X923-Padding scheme for last byte", i, j) } } } } func TestISO10126(t *testing.T) { message := make([]byte, 249) for i, b := range blocksizes { for j, m := range msglengths { msg := message[:m] generateSequence(msg, uint32((m+b)*i)) iso := NewISO10126(b, rand.Reader) pad := iso.Pad(msg) if expected := len(msg) + iso.Overhead(msg); expected != len(pad) { t.Fatalf("Block: %d Message: %d\nOverhead failed: Found: %d Expected: %d", i, j, len(pad), expected) } if len(pad)%b != 0 { t.Fatalf("Block: %d Message: %d\nPadded block not a multiply of blocksize %d", i, j, len(pad)) } unpad, err := iso.Unpad(pad) if err != nil { t.Fatalf("Block: %d Message: %d\nUnpad failed: %s", i, j, err) } if !bytes.Equal(msg, unpad) { t.Fatalf("Block: %d Message: %d\nUnpad does not produces orginal msg", i, j) } if int(pad[len(pad)-1]) != len(pad)-len(msg) { t.Fatalf("Block: %d Message: %d\nISO10126 does not use ISO10126-Padding scheme for last byte", i, j) } } } } var recoverFail = func(t *testing.T, s string) { if err := recover(); err == nil { t.Fatalf("Function: %s\nRecover expected error, but no one occured", s) } } func TestNewPKCS7(t *testing.T) { fail := func(blocksize int) { defer recoverFail(t, "NewPKCS7 with blocksize: "+strconv.Itoa(blocksize)+" failed") NewPKCS7(blocksize) } fail(0) fail(256) } func TestNewX923(t *testing.T) { fail := func(blocksize int) { defer recoverFail(t, "NewX923 with blocksize: "+strconv.Itoa(blocksize)+" failed") NewX923(blocksize) } fail(0) fail(256) } func TestNewISO10126(t *testing.T) { fail := func(blocksize int) { defer recoverFail(t, "NewISO10126 with blocksize: "+strconv.Itoa(blocksize)+" failed") NewISO10126(blocksize, nil) } fail(0) fail(256) } func TestUnpadPKCS7(t *testing.T) { p := NewPKCS7(16) if _, err := p.Unpad(make([]byte, p.BlockSize()-1)); err == nil { t.Fatal("Incomplete block not rejected by PKCS7") } if _, err := p.Unpad(make([]byte, p.BlockSize()+1)); err == nil { t.Fatal("Incomplete block not rejected by PKCS7") } block := make([]byte, p.BlockSize()) if _, err := p.Unpad(block); err == nil { t.Fatal("Block of zeros not rejected by PKCS7") } block[len(block)-1] = byte(p.BlockSize() - 1) if _, err := p.Unpad(block); err == nil { t.Fatal("Invalid padding not rejected by PKCS7") } block[len(block)-1] = byte(p.BlockSize() + 1) if _, err := p.Unpad(block); err == nil { t.Fatal("Invalid padding not rejected by PKCS7") } } func TestUnpadX923(t *testing.T) { p := NewX923(16) if _, err := p.Unpad(make([]byte, p.BlockSize()-1)); err == nil { t.Fatal("Incomplete block not rejected by X923") } if _, err := p.Unpad(make([]byte, p.BlockSize()+1)); err == nil { t.Fatal("Incomplete block not rejected by X923") } block := make([]byte, p.BlockSize()) if _, err := p.Unpad(block); err == nil { t.Fatal("Block of zeros not rejected by X923") } block[len(block)-1] = byte(p.BlockSize() - 1) block[1] = 1 if _, err := p.Unpad(block); err == nil { t.Fatal("Invalid padding not rejected by X923") } block[len(block)-1] = byte(p.BlockSize() + 1) if _, err := p.Unpad(block); err == nil { t.Fatal("Invalid padding not rejected by X923") } } func TestUnpadISO10126(t *testing.T) { p := NewISO10126(16, nil) if _, err := p.Unpad(make([]byte, p.BlockSize()-1)); err == nil { t.Fatal("Incomplete block not rejected by ISO10126") } if _, err := p.Unpad(make([]byte, p.BlockSize()+1)); err == nil { t.Fatal("Incomplete block not rejected by ISO10126") } block := make([]byte, p.BlockSize()) if _, err := p.Unpad(block); err == nil { t.Fatal("Block of zeros not rejected by ISO10126") } block[len(block)-1] = byte(p.BlockSize() + 1) if _, err := p.Unpad(block); err == nil { t.Fatal("Invalid padding not rejected by ISO10126") } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/pad/pkcs7.go000066400000000000000000000022041520706056300236070ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package pad type pkcs7Padding int func (p pkcs7Padding) BlockSize() int { return int(p) } func (p pkcs7Padding) Overhead(src []byte) int { return overhead(p.BlockSize(), src) } func (p pkcs7Padding) Pad(src []byte) []byte { overhead := p.Overhead(src) dst := make([]byte, overhead) for i := range dst { dst[i] = byte(overhead) } return append(src, dst...) } func (p pkcs7Padding) Unpad(src []byte) ([]byte, error) { length := len(src) if length == 0 || length%p.BlockSize() != 0 { return nil, notMulOfBlockErr } block := src[(length - p.BlockSize()):] unLen, err := verifyPkcs7(block, p.BlockSize()) if err != nil { return nil, err } return src[:(length - p.BlockSize() + unLen)], nil } // Verify the PKCS7 padding - NOTICE: not constant time! func verifyPkcs7(block []byte, blocksize int) (p int, err error) { padLen := block[blocksize-1] if padLen == 0 || int(padLen) > blocksize { err = badPadErr return } p = blocksize - int(padLen) for _, b := range block[p:] { if b != padLen { err = badPadErr } } return } golang-github-enceve-crypto-0.0~git20160707.34d48bb/pad/x923.go000066400000000000000000000021651520706056300232730ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package pad type x923Padding int func (p x923Padding) BlockSize() int { return int(p) } func (p x923Padding) Overhead(src []byte) int { return overhead(p.BlockSize(), src) } func (p x923Padding) Pad(src []byte) []byte { overhead := p.Overhead(src) dst := make([]byte, overhead) dst[overhead-1] = byte(overhead) return append(src, dst...) } func (p x923Padding) Unpad(src []byte) ([]byte, error) { length := len(src) if length == 0 || length%p.BlockSize() != 0 { return nil, notMulOfBlockErr } block := src[length-p.BlockSize():] unLen, err := verifyX923(block, p.BlockSize()) if err != nil { return nil, err } return src[:(length - p.BlockSize() + unLen)], nil } // Verify the X923 padding - NOTICE: not constant time! func verifyX923(block []byte, blocksize int) (p int, err error) { padLen := int(block[blocksize-1]) if padLen == 0 || int(padLen) > blocksize { err = badPadErr return } p = blocksize - int(padLen) for _, b := range block[p : blocksize-1] { if b != 0 { err = badPadErr } } return } golang-github-enceve-crypto-0.0~git20160707.34d48bb/poly1305/000077500000000000000000000000001520706056300227635ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/poly1305/poly1305.go000066400000000000000000000104601520706056300246070ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package poly1305 implements Poly1305 one-time message authentication code as // specified in http://cr.yp.to/mac/poly1305-20050329.pdf. // // Poly1305 is a fast, one-time authentication function. It is infeasible for an // attacker to generate an authenticator for a message without the key. // However, a key must only be used for a single message. Authenticating two // different messages with the same key allows an attacker to forge // authenticators for other messages with the same key. // // Poly1305 was originally coupled with AES in order to make Poly1305-AES. // AES was used with a fixed key in order to generate one-time keys from an // nonce. However, in this package AES isn't used and the one-time key is // specified directly. package poly1305 import ( "crypto/subtle" "errors" ) // The size of the poly1305 authentication tag in bytes. const TagSize = 16 const ( msgBlock = uint32(1 << 24) finalBlock = uint32(0) ) // Verify returns true if and only if the mac is a valid authenticator // for msg with the given key. func Verify(mac *[TagSize]byte, msg []byte, key *[32]byte) bool { var sum [TagSize]byte Sum(&sum, msg, key) return subtle.ConstantTimeCompare(sum[:], mac[:]) == 1 } // New returns a hash.Hash computing the poly1305 sum. // Notice that Poly1305 is inseure if one key is used twice. func New(key *[32]byte) *Hash { p := new(Hash) initialize(&(p.r), &(p.pad), key) return p } var writeAfterSumErr error = errors.New("checksum already computed - adding more data is not allowed") // Hash implements a Poly1305 writer interface. // Poly1305 cannot used like common hash.Hash implementations, // beause of using a Poly1305 key twice breaks its security. // So poly1305.Hash does not support some kind of reset. type Hash struct { h, r [5]uint32 pad [4]uint32 buf [TagSize]byte off int done bool } // Write adds more data to the running Poly1305 hash. // This function returns an non-nil error, if a call // to Write happens after the hash's Sum function was // called. So it's not possible to compute the checksum // and than add more data. func (p *Hash) Write(msg []byte) (int, error) { if p.done { return 0, writeAfterSumErr } n := len(msg) if p.off > 0 { dif := TagSize - p.off if n > dif { p.off += copy(p.buf[p.off:], msg[:dif]) msg = msg[dif:] core(p.buf[:], msgBlock, &(p.h), &(p.r)) p.off = 0 } else { p.off += copy(p.buf[p.off:], msg) return n, nil } } length := len(msg) & (^(TagSize - 1)) if length > 0 { core(msg[:length], msgBlock, &(p.h), &(p.r)) msg = msg[length:] } if len(msg) > 0 { p.off += copy(p.buf[p.off:], msg) } return n, nil } // Sum computes the Poly1305 checksum of the prevouisly // processed data and writes it to out. It is legal to // call this function more than one time. func (p *Hash) Sum(out *[TagSize]byte) { h, r := p.h, p.r pad := p.pad if p.off > 0 { var buf [TagSize]byte copy(buf[:], p.buf[:p.off]) buf[p.off] = 1 // invariant: p.off < TagSize core(buf[:], finalBlock, &h, &r) } finalize(out, &h, &pad) p.done = true } func finalize(tag *[TagSize]byte, h *[5]uint32, pad *[4]uint32) { var g0, g1, g2, g3, g4 uint32 // fully carry h h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4] h2 += h1 >> 26 h1 &= 0x3ffffff h3 += h2 >> 26 h2 &= 0x3ffffff h4 += h3 >> 26 h3 &= 0x3ffffff h0 += 5 * (h4 >> 26) h4 &= 0x3ffffff h1 += h0 >> 26 h0 &= 0x3ffffff // h + -p g0 = h0 + 5 g1 = h1 + (g0 >> 26) g0 &= 0x3ffffff g2 = h2 + (g1 >> 26) g1 &= 0x3ffffff g3 = h3 + (g2 >> 26) g2 &= 0x3ffffff g4 = h4 + (g3 >> 26) - (1 << 26) g3 &= 0x3ffffff // select h if h < p else h + -p mask := (g4 >> (32 - 1)) - 1 g0 &= mask g1 &= mask g2 &= mask g3 &= mask g4 &= mask mask = ^mask h0 = (h0 & mask) | g0 h1 = (h1 & mask) | g1 h2 = (h2 & mask) | g2 h3 = (h3 & mask) | g3 h4 = (h4 & mask) | g4 // h %= 2^128 h0 |= h1 << 26 h1 = ((h1 >> 6) | (h2 << 20)) h2 = ((h2 >> 12) | (h3 << 14)) h3 = ((h3 >> 18) | (h4 << 8)) // tag = (h + pad) % (2^128) f := uint64(h0) + uint64(pad[0]) h0 = uint32(f) f = uint64(h1) + uint64(pad[1]) + (f >> 32) h1 = uint32(f) f = uint64(h2) + uint64(pad[2]) + (f >> 32) h2 = uint32(f) f = uint64(h3) + uint64(pad[3]) + (f >> 32) h3 = uint32(f) extractHash(tag, h0, h1, h2, h3) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/poly1305/poly1305_amd64.go000066400000000000000000000045751520706056300256140ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build amd64,!gccgo,!appengine package poly1305 import "unsafe" func initialize(r *[5]uint32, pad *[4]uint32, key *[32]byte) { k0 := *(*uint64)(unsafe.Pointer(&key[0])) k1 := *(*uint64)(unsafe.Pointer(&key[8])) r[0] = uint32(k0) & 0x3ffffff r[1] = uint32(k0>>26) & 0x3ffff03 r[2] = (uint32((k0>>48)|(k1<<16)) >> 4) & 0x3ffc0ff r[3] = uint32(k1>>14) & 0x3f03fff r[4] = uint32(k1>>40) & 0x00fffff pad[0] = *(*uint32)(unsafe.Pointer(&key[16])) pad[1] = *(*uint32)(unsafe.Pointer(&key[20])) pad[2] = *(*uint32)(unsafe.Pointer(&key[24])) pad[3] = *(*uint32)(unsafe.Pointer(&key[28])) } func core(msg []byte, flag uint32, h, r *[5]uint32) { h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4] r0, r1, r2, r3, r4 := uint64(r[0]), uint64(r[1]), uint64(r[2]), uint64(r[3]), uint64(r[4]) s1, s2, s3, s4 := uint64(r[1]*5), uint64(r[2]*5), uint64(r[3]*5), uint64(r[4]*5) var d0, d1, d2, d3, d4 uint64 var m0, m1 uint64 for i := 0; i < len(msg); i += TagSize { m0 = *(*uint64)(unsafe.Pointer(&msg[i])) m1 = *(*uint64)(unsafe.Pointer(&msg[i+8])) // h += m h0 += uint32(m0) & 0x3ffffff h1 += uint32(m0>>26) & 0x3ffffff h2 += (uint32((m0>>48)|(m1<<16)) >> 4) & 0x3ffffff h3 += uint32(m1>>14) & 0x3ffffff h4 += uint32(m1>>40) | flag // h *= r d0 = (uint64(h0) * r0) + (uint64(h1) * s4) + (uint64(h2) * s3) + (uint64(h3) * s2) + (uint64(h4) * s1) d1 = (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * s4) + (uint64(h3) * s3) + (uint64(h4) * s2) d2 = (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * s4) + (uint64(h4) * s3) d3 = (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * s4) d4 = (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0) // h %= p h0 = uint32(d0) & 0x3ffffff h1 = uint32(d1) & 0x3ffffff h2 = uint32(d2) & 0x3ffffff h3 = uint32(d3) & 0x3ffffff h4 = uint32(d4) & 0x3ffffff h0 += uint32(d4>>26) * 5 h1 += h0 >> 26 h0 = h0 & 0x3ffffff } h[0], h[1], h[2], h[3], h[4] = h0, h1, h2, h3, h4 } func extractHash(tag *[16]byte, h0, h1, h2, h3 uint32) { tagPtr := (*[2]uint64)(unsafe.Pointer(&tag[0])) tagPtr[0] = uint64(h0) | (uint64(h1) << 32) tagPtr[1] = uint64(h2) | (uint64(h3) << 32) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/poly1305/poly1305_ref.go000066400000000000000000000064211520706056300254450ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build !amd64 package poly1305 func initialize(r *[5]uint32, pad *[4]uint32, key *[32]byte) { r[0] = (uint32(key[0]) | uint32(key[1])<<8 | uint32(key[2])<<16 | uint32(key[3])<<24) & 0x3ffffff r[1] = ((uint32(key[3]) | uint32(key[4])<<8 | uint32(key[5])<<16 | uint32(key[6])<<24) >> 2) & 0x3ffff03 r[2] = ((uint32(key[6]) | uint32(key[7])<<8 | uint32(key[8])<<16 | uint32(key[9])<<24) >> 4) & 0x3ffc0ff r[3] = ((uint32(key[9]) | uint32(key[10])<<8 | uint32(key[11])<<16 | uint32(key[12])<<24) >> 6) & 0x3f03fff r[4] = ((uint32(key[12]) | uint32(key[13])<<8 | uint32(key[14])<<16 | uint32(key[15])<<24) >> 8) & 0x00fffff pad[0] = (uint32(key[16]) | uint32(key[17])<<8 | uint32(key[18])<<16 | uint32(key[19])<<24) pad[1] = (uint32(key[20]) | uint32(key[21])<<8 | uint32(key[22])<<16 | uint32(key[23])<<24) pad[2] = (uint32(key[24]) | uint32(key[25])<<8 | uint32(key[26])<<16 | uint32(key[27])<<24) pad[3] = (uint32(key[28]) | uint32(key[29])<<8 | uint32(key[30])<<16 | uint32(key[31])<<24) } func core(msg []byte, flag uint32, h, r *[5]uint32) { h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4] r0, r1, r2, r3, r4 := uint64(r[0]), uint64(r[1]), uint64(r[2]), uint64(r[3]), uint64(r[4]) s1, s2, s3, s4 := uint64(r[1]*5), uint64(r[2]*5), uint64(r[3]*5), uint64(r[4]*5) var d0, d1, d2, d3, d4 uint64 for i := 0; i < len(msg); i += TagSize { // h += m h0 += (uint32(msg[i+0]) | uint32(msg[i+1])<<8 | uint32(msg[i+2])<<16 | uint32(msg[i+3])<<24) & 0x3ffffff h1 += ((uint32(msg[i+3]) | uint32(msg[i+4])<<8 | uint32(msg[i+5])<<16 | uint32(msg[i+6])<<24) >> 2) & 0x3ffffff h2 += ((uint32(msg[i+6]) | uint32(msg[i+7])<<8 | uint32(msg[i+8])<<16 | uint32(msg[i+9])<<24) >> 4) & 0x3ffffff h3 += ((uint32(msg[i+9]) | uint32(msg[i+10])<<8 | uint32(msg[i+11])<<16 | uint32(msg[i+12])<<24) >> 6) & 0x3ffffff h4 += ((uint32(msg[i+12]) | uint32(msg[i+13])<<8 | uint32(msg[i+14])<<16 | uint32(msg[i+15])<<24) >> 8) | flag // h *= r d0 = (uint64(h0) * r0) + (uint64(h1) * s4) + (uint64(h2) * s3) + (uint64(h3) * s2) + (uint64(h4) * s1) d1 = (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * s4) + (uint64(h3) * s3) + (uint64(h4) * s2) d2 = (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * s4) + (uint64(h4) * s3) d3 = (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * s4) d4 = (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0) // h %= p h0 = uint32(d0) & 0x3ffffff h1 = uint32(d1) & 0x3ffffff h2 = uint32(d2) & 0x3ffffff h3 = uint32(d3) & 0x3ffffff h4 = uint32(d4) & 0x3ffffff h0 += uint32(d4>>26) * 5 h1 += h0 >> 26 h0 = h0 & 0x3ffffff } h[0], h[1], h[2], h[3], h[4] = h0, h1, h2, h3, h4 } func extractHash(tag *[16]byte, h0, h1, h2, h3 uint32) { tag[0] = byte(h0) tag[1] = byte(h0 >> 8) tag[2] = byte(h0 >> 16) tag[3] = byte(h0 >> 24) tag[4] = byte(h1) tag[5] = byte(h1 >> 8) tag[6] = byte(h1 >> 16) tag[7] = byte(h1 >> 24) tag[8] = byte(h2) tag[9] = byte(h2 >> 8) tag[10] = byte(h2 >> 16) tag[11] = byte(h2 >> 24) tag[12] = byte(h3) tag[13] = byte(h3 >> 8) tag[14] = byte(h3 >> 16) tag[15] = byte(h3 >> 24) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/poly1305/poly1305_test.go000066400000000000000000000066221520706056300256530ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package poly1305 import ( "encoding/hex" "testing" "unsafe" ) func TestWriteAfterSum(t *testing.T) { var sum [TagSize]byte msg := make([]byte, 64) for i := range msg { h := New(new([32]byte)) if _, err := h.Write(msg[:i]); err != nil { t.Fatalf("Iteration %d: poly1305.Hash returned unexpected error: %s", i, err) } h.Sum(&sum) if _, err := h.Write(nil); err == nil { t.Fatalf("Iteration %d: poly1305.Hash returned no error for write after sum", i) } } } func TestWrite(t *testing.T) { var key [32]byte for i := range key { key[i] = byte(i) } h := New(&key) var msg1 []byte msg0 := make([]byte, 64) for i := range msg0 { h.Write(msg0[:i]) msg1 = append(msg1, msg0[:i]...) } var tag0, tag1 [TagSize]byte h.Sum(&tag0) Sum(&tag1, msg1, &key) if tag0 != tag1 { t.Fatalf("Sum differ from poly1305.Sum\n Sum: %s \n poly1305.Sum: %s", hex.EncodeToString(tag0[:]), hex.EncodeToString(tag1[:])) } } func TestSum(t *testing.T) { var key [32]byte for i := range key { key[i] = byte(i) } msg := make([]byte, 64) var tag, sum [TagSize]byte for i := range msg { h := New(&key) h.Write(msg[:i]) h.Sum(&sum) Sum(&tag, msg[:i], &key) if tag != sum { t.Fatalf("Iteration %d: Sum differ from poly1305.Sum\n Sum: %s \n poly1305.Sum %s", i, hex.EncodeToString(sum[:]), hex.EncodeToString(tag[:])) } } } func TestVerify(t *testing.T) { for i, v := range vectors { key, err := hex.DecodeString(v.key) if err != nil { t.Fatalf("Test vector %d : Failed to decode key: %s", i, err) } msg, err := hex.DecodeString(v.msg) if err != nil { t.Fatalf("Test vector %d : Failed to decode msg: %s", i, err) } tag, err := hex.DecodeString(v.tag) if err != nil { t.Fatalf("Test vector %d : Failed to decode tag: %s", i, err) } var sum [TagSize]byte var k [32]byte copy(k[:], key) copy(sum[:], tag) if !Verify(&sum, msg, &k) { t.Fatalf("Test vector %d : Poly1305 Verification failed", i) } } } // Benchmarks func BenchmarkSum_8(b *testing.B) { benchmarkSum(b, 8, false) } func BenchmarkSumUnaligned_8(b *testing.B) { benchmarkSum(b, 8, true) } func BenchmarkSum_4K(b *testing.B) { benchmarkSum(b, 4*1024, false) } func BenchmarkSumUnaligned_4K(b *testing.B) { benchmarkSum(b, 4*1024, true) } func BenchmarkWrite_8(b *testing.B) { benchmarkWrite(b, 8, false) } func BenchmarkWriteUnaligned_8(b *testing.B) { benchmarkWrite(b, 8, true) } func BenchmarkWrite_4K(b *testing.B) { benchmarkWrite(b, 4*1024, false) } func BenchmarkWriteUnaligned_4K(b *testing.B) { benchmarkWrite(b, 4*1024, true) } func benchmarkSum(b *testing.B, size int, unalign bool) { var key [32]byte var tag [16]byte msg := make([]byte, size) if unalign { msg = unalignBytes(msg) } b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { Sum(&tag, msg, &key) } } func benchmarkWrite(b *testing.B, size int, unalign bool) { var key [32]byte h := New(&key) msg := make([]byte, size) if unalign { msg = unalignBytes(msg) } b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { h.Write(msg) } } func unalignBytes(in []byte) []byte { out := make([]byte, len(in)+1) if uintptr(unsafe.Pointer(&out[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { out = out[1:] } else { out = out[:len(in)] } copy(out, in) return out } golang-github-enceve-crypto-0.0~git20160707.34d48bb/poly1305/sum.go000066400000000000000000000007031520706056300241160ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package poly1305 import poly "golang.org/x/crypto/poly1305" // Sum generates an authenticator for msg using a one-time key and puts the // 16-byte result into out. Authenticating two different messages with the same // key allows an attacker to forge messages at will. func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) { poly.Sum(out, msg, key) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/poly1305/vectors_test.go000066400000000000000000000025251520706056300260420ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package poly1305 import ( "bytes" "encoding/hex" "testing" ) type testVector struct { key, msg, tag string } var vectors = []testVector{ // From: https://tools.ietf.org/html/rfc7539#section-2.5.2 testVector{ key: "85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b", msg: "43727970746f6772617068696320466f72756d2052657365617263682047726f7570", tag: "a8061dc1305136c6c22b8baf0c0127a9", }, } func TestVectors(t *testing.T) { for i, v := range vectors { key, err := hex.DecodeString(v.key) if err != nil { t.Fatalf("Test vector %d : Failed to decode key: %s", i, err) } msg, err := hex.DecodeString(v.msg) if err != nil { t.Fatalf("Test vector %d : Failed to decode msg: %s", i, err) } tag, err := hex.DecodeString(v.tag) if err != nil { t.Fatalf("Test vector %d : Failed to decode tag: %s", i, err) } var sum [TagSize]byte var k [32]byte copy(k[:], key) Sum(&sum, msg, &k) if !bytes.Equal(sum[:], tag) { t.Fatalf("Test vector %d : Poly1305 Tags are not equal:\nFound: %v\nExpected: %v", i, sum, tag) } p := New(&k) p.Write(msg) p.Sum(&sum) if !bytes.Equal(sum[:], tag) { t.Fatalf("Test vector %d : Poly1305 Tags are not equal:\nFound: %v\nExpected: %v", i, sum[:], tag) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/serpent/000077500000000000000000000000001520706056300231475ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/serpent/sbox_386.go000066400000000000000000000153311520706056300250540ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build 386 package serpent // The linear transformation of serpent. // This version, tries to minimize the number // of registers (x86). func linear(v0, v1, v2, v3 *uint32) { *v0 = ((*v0 << 13) | (*v0 >> (32 - 13))) *v2 = ((*v2 << 3) | (*v2 >> (32 - 3))) *v1 ^= *v0 ^ *v2 *v3 ^= *v2 ^ (*v0 << 3) *v1 = (*v1 << 1) | (*v1 >> (32 - 1)) *v3 = (*v3 << 7) | (*v3 >> (32 - 7)) *v0 ^= *v1 ^ *v3 *v2 ^= *v3 ^ (*v1 << 7) *v0 = (*v0 << 5) | (*v0 >> (32 - 5)) *v2 = (*v2 << 22) | (*v2 >> (32 - 22)) } // The inverse linear transformation of serpent. // This version, tries to minimize the number // of registers (x86). func linearInv(v0, v1, v2, v3 *uint32) { *v2 = (*v2 >> 22) | (*v2 << (32 - 22)) *v0 = (*v0 >> 5) | (*v0 << (32 - 5)) *v2 ^= *v3 ^ (*v1 << 7) *v0 ^= *v1 ^ *v3 *v3 = (*v3 >> 7) | (*v3 << (32 - 7)) *v1 = (*v1 >> 1) | (*v1 << (32 - 1)) *v3 ^= *v2 ^ (*v0 << 3) *v1 ^= *v0 ^ *v2 *v2 = (*v2 >> 3) | (*v2 << (32 - 3)) *v0 = (*v0 >> 13) | (*v0 << (32 - 13)) } // The following functions sb0,sb1, ..., sb7 represent the 8 Serpent S-Boxes. // sb0Inv til sb7Inv are the inverse functions (e.g. sb0Inv is the Inverse to sb0 // and vice versa). // The S-Boxes differ from the original Serpent definitions. This is for // optimisation. The functions use the Serpent S-Box improvements for x86 // from Dag Arne Osvik described in http://www.ii.uib.no/~osvik/pub/aes3.pdf. // S-Box 0 func sb0(r0, r1, r2, r3 *uint32) { *r3 ^= *r0 r4 := *r1 *r1 &= *r3 r4 ^= *r2 *r1 ^= *r0 *r0 |= *r3 *r0 ^= r4 r4 ^= *r3 *r3 ^= *r2 *r2 |= *r1 *r2 ^= r4 r4 = ^r4 r4 |= *r1 *r1 ^= *r3 *r1 ^= r4 *r3 |= *r0 *r1 ^= *r3 r4 ^= *r3 //return *r1, r4, *r2, *r0 *r3 = *r0 *r0 = *r1 *r1 = r4 } // Inverse S-Box 0 func sb0Inv(r0, r1, r2, r3 *uint32) { *r2 = ^*r2 r4 := *r1 *r1 |= *r0 r4 = ^r4 *r1 ^= *r2 *r2 |= r4 *r1 ^= *r3 *r0 ^= r4 *r2 ^= *r0 *r0 &= *r3 r4 ^= *r0 *r0 |= *r1 *r0 ^= *r2 *r3 ^= r4 *r2 ^= *r1 *r3 ^= *r0 *r3 ^= *r1 *r2 &= *r3 r4 ^= *r2 //return *r0, r4, *r1, *r3 *r2 = *r1 *r1 = r4 } // S-Box 1 func sb1(r0, r1, r2, r3 *uint32) { *r0 = ^*r0 *r2 = ^*r2 r4 := *r0 *r0 &= *r1 *r2 ^= *r0 *r0 |= *r3 *r3 ^= *r2 *r1 ^= *r0 *r0 ^= r4 r4 |= *r1 *r1 ^= *r3 *r2 |= *r0 *r2 &= r4 *r0 ^= *r1 *r1 &= *r2 *r1 ^= *r0 *r0 &= *r2 *r0 ^= r4 // return *r2, *r0, *r3, *r1 r4 = *r0 *r0 = *r2 *r2 = *r3 *r3 = *r1 *r1 = r4 } // Inverse S-Box 1 func sb1Inv(r0, r1, r2, r3 *uint32) { r4 := *r1 *r1 ^= *r3 *r3 &= *r1 r4 ^= *r2 *r3 ^= *r0 *r0 |= *r1 *r2 ^= *r3 *r0 ^= r4 *r0 |= *r2 *r1 ^= *r3 *r0 ^= *r1 *r1 |= *r3 *r1 ^= *r0 r4 = ^r4 r4 ^= *r1 *r1 |= *r0 *r1 ^= *r0 *r1 |= r4 *r3 ^= *r1 // return r4, *r0, *r3, *r2 *r1 = *r0 *r0 = r4 r4 = *r3 *r3 = *r2 *r2 = r4 } // S-Box 2 func sb2(r0, r1, r2, r3 *uint32) { r4 := *r0 *r0 &= *r2 *r0 ^= *r3 *r2 ^= *r1 *r2 ^= *r0 *r3 |= r4 *r3 ^= *r1 r4 ^= *r2 *r1 = *r3 *r3 |= r4 *r3 ^= *r0 *r0 &= *r1 r4 ^= *r0 *r1 ^= *r3 *r1 ^= r4 r4 = ^r4 //return *r2, *r3, *r1, r4 *r0 = *r2 *r2 = *r1 *r1 = *r3 *r3 = r4 } // Inverse S-Box 2 func sb2Inv(r0, r1, r2, r3 *uint32) { *r2 ^= *r3 *r3 ^= *r0 r4 := *r3 *r3 &= *r2 *r3 ^= *r1 *r1 |= *r2 *r1 ^= r4 r4 &= *r3 *r2 ^= *r3 r4 &= *r0 r4 ^= *r2 *r2 &= *r1 *r2 |= *r0 *r3 = ^*r3 *r2 ^= *r3 *r0 ^= *r3 *r0 &= *r1 *r3 ^= r4 *r3 ^= *r0 //return *r1, r4, *r2, *r3 *r0 = *r1 *r1 = r4 } // S-Box 3 func sb3(r0, r1, r2, r3 *uint32) { r4 := *r0 *r0 |= *r3 *r3 ^= *r1 *r1 &= r4 r4 ^= *r2 *r2 ^= *r3 *r3 &= *r0 r4 |= *r1 *r3 ^= r4 *r0 ^= *r1 r4 &= *r0 *r1 ^= *r3 r4 ^= *r2 *r1 |= *r0 *r1 ^= *r2 *r0 ^= *r3 *r2 = *r1 *r1 |= *r3 *r1 ^= *r0 //return *r1, *r2, *r3, r4 *r0 = *r1 *r1 = *r2 *r2 = *r3 *r3 = r4 } // Inverse S-Box 3 func sb3Inv(r0, r1, r2, r3 *uint32) { r4 := *r2 *r2 ^= *r1 *r0 ^= *r2 r4 &= *r2 r4 ^= *r0 *r0 &= *r1 *r1 ^= *r3 *r3 |= r4 *r2 ^= *r3 *r0 ^= *r3 *r1 ^= r4 *r3 &= *r2 *r3 ^= *r1 *r1 ^= *r0 *r1 |= *r2 *r0 ^= *r3 *r1 ^= r4 *r0 ^= *r1 //return *r2, *r1, *r3, *r0 r4 = *r0 *r0 = *r2 *r2 = *r3 *r3 = r4 } // S-Box 4 func sb4(r0, r1, r2, r3 *uint32) { *r1 ^= *r3 *r3 = ^*r3 *r2 ^= *r3 *r3 ^= *r0 r4 := *r1 *r1 &= *r3 *r1 ^= *r2 r4 ^= *r3 *r0 ^= r4 *r2 &= r4 *r2 ^= *r0 *r0 &= *r1 *r3 ^= *r0 r4 |= *r1 r4 ^= *r0 *r0 |= *r3 *r0 ^= *r2 *r2 &= *r3 *r0 = ^*r0 r4 ^= *r2 //return *r1, r4, *r0, *r3 *r2 = *r0 *r0 = *r1 *r1 = r4 } // Inverse S-Box 4 func sb4Inv(r0, r1, r2, r3 *uint32) { r4 := *r2 *r2 &= *r3 *r2 ^= *r1 *r1 |= *r3 *r1 &= *r0 r4 ^= *r2 r4 ^= *r1 *r1 &= *r2 *r0 = ^*r0 *r3 ^= r4 *r1 ^= *r3 *r3 &= *r0 *r3 ^= *r2 *r0 ^= *r1 *r2 &= *r0 *r3 ^= *r0 *r2 ^= r4 *r2 |= *r3 *r3 ^= *r0 *r2 ^= *r1 //return *r0, *r3, *r2, r4 *r1 = *r3 *r3 = r4 } // S-Box 5 func sb5(r0, r1, r2, r3 *uint32) { *r0 ^= *r1 *r1 ^= *r3 *r3 = ^*r3 r4 := *r1 *r1 &= *r0 *r2 ^= *r3 *r1 ^= *r2 *r2 |= r4 r4 ^= *r3 *r3 &= *r1 *r3 ^= *r0 r4 ^= *r1 r4 ^= *r2 *r2 ^= *r0 *r0 &= *r3 *r2 = ^*r2 *r0 ^= r4 r4 |= *r3 *r2 ^= r4 //return *r1, *r3, *r0, *r2 r4 = *r0 *r0 = *r1 *r1 = *r3 *r3 = *r2 *r2 = r4 } // Inverse S-Box 5 func sb5Inv(r0, r1, r2, r3 *uint32) { *r1 = ^*r1 r4 := *r3 *r2 ^= *r1 *r3 |= *r0 *r3 ^= *r2 *r2 |= *r1 *r2 &= *r0 r4 ^= *r3 *r2 ^= r4 r4 |= *r0 r4 ^= *r1 *r1 &= *r2 *r1 ^= *r3 r4 ^= *r2 *r3 &= r4 r4 ^= *r1 *r3 ^= r4 r4 = ^r4 *r3 ^= *r0 //return *r1, r4, *r3, *r2 *r0 = *r1 *r1 = r4 r4 = *r3 *r3 = *r2 *r2 = r4 } // S-Box 6 func sb6(r0, r1, r2, r3 *uint32) { *r2 = ^*r2 r4 := *r3 *r3 &= *r0 *r0 ^= r4 *r3 ^= *r2 *r2 |= r4 *r1 ^= *r3 *r2 ^= *r0 *r0 |= *r1 *r2 ^= *r1 r4 ^= *r0 *r0 |= *r3 *r0 ^= *r2 r4 ^= *r3 r4 ^= *r0 *r3 = ^*r3 *r2 &= r4 *r2 ^= *r3 //return *r0, *r1, r4, *r2 *r3 = *r2 *r2 = r4 } // Inverse S-Box 6 func sb6Inv(r0, r1, r2, r3 *uint32) { *r0 ^= *r2 r4 := *r2 *r2 &= *r0 r4 ^= *r3 *r2 = ^*r2 *r3 ^= *r1 *r2 ^= *r3 r4 |= *r0 *r0 ^= *r2 *r3 ^= r4 r4 ^= *r1 *r1 &= *r3 *r1 ^= *r0 *r0 ^= *r3 *r0 |= *r2 *r3 ^= *r1 r4 ^= *r0 // return *r1, *r2, r4, *r3 *r0 = *r1 *r1 = *r2 *r2 = r4 } // S-Box 7 func sb7(r0, r1, r2, r3 *uint32) { r4 := *r1 *r1 |= *r2 *r1 ^= *r3 r4 ^= *r2 *r2 ^= *r1 *r3 |= r4 *r3 &= *r0 r4 ^= *r2 *r3 ^= *r1 *r1 |= r4 *r1 ^= *r0 *r0 |= r4 *r0 ^= *r2 *r1 ^= r4 *r2 ^= *r1 *r1 &= *r0 *r1 ^= r4 *r2 = ^*r2 *r2 |= *r0 r4 ^= *r2 // return r4, *r3, *r1, *r0 *r2 = *r1 *r1 = *r3 *r3 = *r0 *r0 = r4 } // Inverse S-Box 7 func sb7Inv(r0, r1, r2, r3 *uint32) { r4 := *r2 *r2 ^= *r0 *r0 &= *r3 r4 |= *r3 *r2 = ^*r2 *r3 ^= *r1 *r1 |= *r0 *r0 ^= *r2 *r2 &= r4 *r3 &= r4 *r1 ^= *r2 *r2 ^= *r0 *r0 |= *r2 r4 ^= *r1 *r0 ^= *r3 *r3 ^= r4 r4 |= *r0 *r3 ^= *r2 r4 ^= *r2 // return *r3, *r0, *r1, r4 *r2 = *r1 *r1 = *r0 *r0 = *r3 *r3 = r4 } golang-github-enceve-crypto-0.0~git20160707.34d48bb/serpent/sbox_ref.go000066400000000000000000000136631520706056300253160ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build !386 package serpent // The linear transformation of serpent // This version, tries not to minimize the // number of registers, but maximize parallism. func linear(v0, v1, v2, v3 *uint32) { t0 := ((*v0 << 13) | (*v0 >> (32 - 13))) t2 := ((*v2 << 3) | (*v2 >> (32 - 3))) t1 := *v1 ^ t0 ^ t2 t3 := *v3 ^ t2 ^ (t0 << 3) *v1 = (t1 << 1) | (t1 >> (32 - 1)) *v3 = (t3 << 7) | (t3 >> (32 - 7)) t0 ^= *v1 ^ *v3 t2 ^= *v3 ^ (*v1 << 7) *v0 = (t0 << 5) | (t0 >> (32 - 5)) *v2 = (t2 << 22) | (t2 >> (32 - 22)) } // The inverse linear transformation of serpent // This version, tries not to minimize the // number of registers, but maximize parallism. func linearInv(v0, v1, v2, v3 *uint32) { t2 := (*v2 >> 22) | (*v2 << (32 - 22)) t0 := (*v0 >> 5) | (*v0 << (32 - 5)) t2 ^= *v3 ^ (*v1 << 7) t0 ^= *v1 ^ *v3 t3 := (*v3 >> 7) | (*v3 << (32 - 7)) t1 := (*v1 >> 1) | (*v1 << (32 - 1)) *v3 = t3 ^ t2 ^ (t0 << 3) *v1 = t1 ^ t0 ^ t2 *v2 = (t2 >> 3) | (t2 << (32 - 3)) *v0 = (t0 >> 13) | (t0 << (32 - 13)) } // The following functions sb0,sb1, ..., sb7 represent the 8 Serpent S-Boxes. // sb0Inv til sb7Inv are the inverse functions (e.g. sb0Inv is the Inverse to sb0 // and vice versa). // The S-Boxes differ from the original Serpent definitions. This is for // optimisation. The functions use the Serpent S-Box improvements for (non x86) // from Dr. B. R. Gladman and Sam Simpson. // S-Box 0 func sb0(r0, r1, r2, r3 *uint32) { t0 := *r0 ^ *r3 t1 := *r2 ^ t0 t2 := *r1 ^ t1 *r3 = (*r0 & *r3) ^ t2 t3 := *r0 ^ (*r1 & t0) *r2 = t2 ^ (*r2 | t3) t4 := *r3 & (t1 ^ t3) *r1 = (^t1) ^ t4 *r0 = t4 ^ (^t3) } // Inverse S-Box 0 func sb0Inv(r0, r1, r2, r3 *uint32) { t0 := ^(*r0) t1 := *r0 ^ *r1 t2 := *r3 ^ (t0 | t1) t3 := *r2 ^ t2 *r2 = t1 ^ t3 t4 := t0 ^ (*r3 & t1) *r1 = t2 ^ (*r2 & t4) *r3 = (*r0 & t2) ^ (t3 | *r1) *r0 = *r3 ^ (t3 ^ t4) } // S-Box 1 func sb1(r0, r1, r2, r3 *uint32) { t0 := *r1 ^ (^(*r0)) t1 := *r2 ^ (*r0 | t0) *r2 = *r3 ^ t1 t2 := *r1 ^ (*r3 | t0) t3 := t0 ^ *r2 *r3 = t3 ^ (t1 & t2) t4 := t1 ^ t2 *r1 = *r3 ^ t4 *r0 = t1 ^ (t3 & t4) } // Inverse S-Box 1 func sb1Inv(r0, r1, r2, r3 *uint32) { t0 := *r1 ^ *r3 t1 := *r0 ^ (*r1 & t0) t2 := t0 ^ t1 *r3 = *r2 ^ t2 t3 := *r1 ^ (t0 & t1) t4 := *r3 | t3 *r1 = t1 ^ t4 t5 := ^(*r1) t6 := *r3 ^ t3 *r0 = t5 ^ t6 *r2 = t2 ^ (t5 | t6) } // S-Box 2 func sb2(r0, r1, r2, r3 *uint32) { v0 := *r0 // save r0 v3 := *r3 // save r3 t0 := ^v0 t1 := *r1 ^ v3 t2 := *r2 & t0 *r0 = t1 ^ t2 t3 := *r2 ^ t0 t4 := *r2 ^ *r0 t5 := *r1 & t4 *r3 = t3 ^ t5 *r2 = v0 ^ ((v3 | t5) & (*r0 | t3)) *r1 = (t1 ^ *r3) ^ (*r2 ^ (v3 | t0)) } // Inverse S-Box 2 func sb2Inv(r0, r1, r2, r3 *uint32) { v0 := *r0 // save r0 v3 := *r3 // save r3 t0 := *r1 ^ v3 t1 := ^t0 t2 := v0 ^ *r2 t3 := *r2 ^ t0 t4 := *r1 & t3 *r0 = t2 ^ t4 t5 := v0 | t1 t6 := v3 ^ t5 t7 := t2 | t6 *r3 = t0 ^ t7 t8 := ^t3 t9 := *r0 | *r3 *r1 = t8 ^ t9 *r2 = (v3 & t8) ^ (t2 ^ t9) } // S-Box 3 func sb3(r0, r1, r2, r3 *uint32) { v1 := *r1 // save r1 v3 := *r3 // save r3 t0 := *r0 ^ *r1 t1 := *r0 & *r2 t2 := *r0 | *r3 t3 := *r2 ^ *r3 t4 := t0 & t2 t5 := t1 | t4 *r2 = t3 ^ t5 t6 := *r1 ^ t2 t7 := t5 ^ t6 t8 := t3 & t7 *r0 = t0 ^ t8 t9 := *r2 & *r0 *r1 = t7 ^ t9 *r3 = (v1 | v3) ^ (t3 ^ t9) } // Inverse S-Box 3 func sb3Inv(r0, r1, r2, r3 *uint32) { t0 := *r0 | *r1 t1 := *r1 ^ *r2 t2 := *r1 & t1 t3 := *r0 ^ t2 t4 := *r2 ^ t3 t5 := *r3 | t3 *r0 = t1 ^ t5 t6 := t1 | t5 t7 := *r3 ^ t6 *r2 = t4 ^ t7 t8 := t0 ^ t7 t9 := *r0 & t8 *r3 = t3 ^ t9 *r1 = *r3 ^ (*r0 ^ t8) } // S-Box 4 func sb4(r0, r1, r2, r3 *uint32) { v0 := *r0 // save r0 t0 := v0 ^ *r3 t1 := *r3 & t0 t2 := *r2 ^ t1 t3 := *r1 | t2 *r3 = t0 ^ t3 t4 := ^(*r1) t5 := t0 | t4 *r0 = t2 ^ t5 t6 := v0 & *r0 t7 := t0 ^ t4 t8 := t3 & t7 *r2 = t6 ^ t8 *r1 = (v0 ^ t2) ^ (t7 & *r2) } // Inverse S-Box 4 func sb4Inv(r0, r1, r2, r3 *uint32) { v3 := *r3 // save r3 t0 := *r2 | v3 t1 := *r0 & t0 t2 := *r1 ^ t1 t3 := *r0 & t2 t4 := *r2 ^ t3 *r1 = v3 ^ t4 t5 := ^(*r0) t6 := t4 & *r1 *r3 = t2 ^ t6 t7 := *r1 | t5 t8 := v3 ^ t7 *r0 = *r3 ^ t8 *r2 = (t2 & t8) ^ (*r1 ^ t5) } // S-Box 5 func sb5(r0, r1, r2, r3 *uint32) { v1 := *r1 // save r1 t0 := ^(*r0) t1 := *r0 ^ v1 t2 := *r0 ^ *r3 t3 := *r2 ^ t0 t4 := t1 | t2 *r0 = t3 ^ t4 t5 := *r3 & *r0 t6 := t1 ^ *r0 *r1 = t5 ^ t6 t7 := t0 | *r0 t8 := t1 | t5 t9 := t2 ^ t7 *r2 = t8 ^ t9 *r3 = (v1 ^ t5) ^ (*r1 & t9) } // Inverse S-Box 5 func sb5Inv(r0, r1, r2, r3 *uint32) { v0 := *r0 // save r0 v1 := *r1 // save r1 v3 := *r3 // save r3 t0 := ^(*r2) t1 := v1 & t0 t2 := v3 ^ t1 t3 := v0 & t2 t4 := v1 ^ t0 *r3 = t3 ^ t4 t5 := v1 | *r3 t6 := v0 & t5 *r1 = t2 ^ t6 t7 := v0 | v3 t8 := t0 ^ t5 *r0 = t7 ^ t8 *r2 = (v1 & t7) ^ (t3 | (v0 ^ *r2)) } // S-Box 6 func sb6(r0, r1, r2, r3 *uint32) { t0 := ^(*r0) t1 := *r0 ^ *r3 t2 := *r1 ^ t1 t3 := t0 | t1 t4 := *r2 ^ t3 *r1 = *r1 ^ t4 t5 := t1 | *r1 t6 := *r3 ^ t5 t7 := t4 & t6 *r2 = t2 ^ t7 t8 := t4 ^ t6 *r0 = *r2 ^ t8 *r3 = (^t4) ^ (t2 & t8) } // Inverse S-Box 6 func sb6Inv(r0, r1, r2, r3 *uint32) { v1 := *r1 // save r1 v3 := *r3 // save r3 t0 := ^(*r0) t1 := *r0 ^ v1 t2 := *r2 ^ t1 t3 := *r2 | t0 t4 := v3 ^ t3 *r1 = t2 ^ t4 t5 := t2 & t4 t6 := t1 ^ t5 t7 := v1 | t6 *r3 = t4 ^ t7 t8 := v1 | *r3 *r0 = t6 ^ t8 *r2 = (v3 & t0) ^ (t2 ^ t8) } // S-Box 7 func sb7(r0, r1, r2, r3 *uint32) { t0 := *r1 ^ *r2 t1 := *r2 & t0 t2 := *r3 ^ t1 t3 := *r0 ^ t2 t4 := *r3 | t0 t5 := t3 & t4 *r1 = *r1 ^ t5 t6 := t2 | *r1 t7 := *r0 & t3 *r3 = t0 ^ t7 t8 := t3 ^ t6 t9 := *r3 & t8 *r2 = t2 ^ t9 *r0 = (^t8) ^ (*r3 & *r2) } // Inverse S-Box 7 func sb7Inv(r0, r1, r2, r3 *uint32) { v0 := *r0 // save r0 v3 := *r3 // save r3 t0 := *r2 | (v0 & *r1) t1 := v3 & (v0 | *r1) *r3 = t0 ^ t1 t2 := ^v3 t3 := *r1 ^ t1 t4 := t3 | (*r3 ^ t2) *r1 = v0 ^ t4 *r0 = (*r2 ^ t3) ^ (v3 | *r1) *r2 = (t0 ^ *r1) ^ (*r0 ^ (v0 & *r3)) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/serpent/serpent.go000066400000000000000000000061601520706056300251610ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package serpent implements the Serpent block cipher // submitted to the AES challenge. Serpent was designed by // Ross Anderson, Eli Biham und Lars Knudsen. // The block cipher takes a 128, 192 or 256 bit key and // has a block size of 128 bit. package serpent import ( "crypto/cipher" "github.com/enceve/crypto" ) // The Serpent block size in bytes. const BlockSize = 16 // NewCipher returns a new cipher.Block implementing the serpent block cipher. // The key argument must be 128, 192 or 256 bit (16, 24, 32 byte). func NewCipher(key []byte) (cipher.Block, error) { if k := len(key); k != 16 && k != 24 && k != 32 { return nil, crypto.KeySizeError(k) } s := &subkeys{} s.keySchedule(key) return s, nil } // The 132 32 bit subkeys of serpent type subkeys [132]uint32 func (s *subkeys) BlockSize() int { return BlockSize } func (s *subkeys) Encrypt(dst, src []byte) { if len(src) < BlockSize { panic("src buffer to small") } if len(dst) < BlockSize { panic("dst buffer to small") } encryptBlock(dst, src, s) } func (s *subkeys) Decrypt(dst, src []byte) { if len(src) < BlockSize { panic("src buffer to small") } if len(dst) < BlockSize { panic("dst buffer to small") } decryptBlock(dst, src, s) } const phi = 0x9e3779b9 // The Serpent phi constant (sqrt(5) - 1) * 2**31 // The key schedule of serpent. func (s *subkeys) keySchedule(key []byte) { var k [16]uint32 j := 0 for i := 0; i+4 <= len(key); i += 4 { k[j] = uint32(key[i]) | uint32(key[i+1])<<8 | uint32(key[i+2])<<16 | uint32(key[i+3])<<24 j++ } if j < 8 { k[j] = 1 } for i := 8; i < 16; i++ { x := k[i-8] ^ k[i-5] ^ k[i-3] ^ k[i-1] ^ phi ^ uint32(i-8) k[i] = (x << 11) | (x >> 21) s[i-8] = k[i] } for i := 8; i < 132; i++ { x := s[i-8] ^ s[i-5] ^ s[i-3] ^ s[i-1] ^ phi ^ uint32(i) s[i] = (x << 11) | (x >> 21) } sb3(&s[0], &s[1], &s[2], &s[3]) sb2(&s[4], &s[5], &s[6], &s[7]) sb1(&s[8], &s[9], &s[10], &s[11]) sb0(&s[12], &s[13], &s[14], &s[15]) sb7(&s[16], &s[17], &s[18], &s[19]) sb6(&s[20], &s[21], &s[22], &s[23]) sb5(&s[24], &s[25], &s[26], &s[27]) sb4(&s[28], &s[29], &s[30], &s[31]) sb3(&s[32], &s[33], &s[34], &s[35]) sb2(&s[36], &s[37], &s[38], &s[39]) sb1(&s[40], &s[41], &s[42], &s[43]) sb0(&s[44], &s[45], &s[46], &s[47]) sb7(&s[48], &s[49], &s[50], &s[51]) sb6(&s[52], &s[53], &s[54], &s[55]) sb5(&s[56], &s[57], &s[58], &s[59]) sb4(&s[60], &s[61], &s[62], &s[63]) sb3(&s[64], &s[65], &s[66], &s[67]) sb2(&s[68], &s[69], &s[70], &s[71]) sb1(&s[72], &s[73], &s[74], &s[75]) sb0(&s[76], &s[77], &s[78], &s[79]) sb7(&s[80], &s[81], &s[82], &s[83]) sb6(&s[84], &s[85], &s[86], &s[87]) sb5(&s[88], &s[89], &s[90], &s[91]) sb4(&s[92], &s[93], &s[94], &s[95]) sb3(&s[96], &s[97], &s[98], &s[99]) sb2(&s[100], &s[101], &s[102], &s[103]) sb1(&s[104], &s[105], &s[106], &s[107]) sb0(&s[108], &s[109], &s[110], &s[111]) sb7(&s[112], &s[113], &s[114], &s[115]) sb6(&s[116], &s[117], &s[118], &s[119]) sb5(&s[120], &s[121], &s[122], &s[123]) sb4(&s[124], &s[125], &s[126], &s[127]) sb3(&s[128], &s[129], &s[130], &s[131]) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/serpent/serpent_ref.go000066400000000000000000000227501520706056300260200ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package serpent // Encrypts one block with the given 132 sub-keys sk. func encryptBlock(dst, src []byte, sk *subkeys) { // Transform the input block to 4 x 32 bit registers r0 := uint32(src[0]) | uint32(src[1])<<8 | uint32(src[2])<<16 | uint32(src[3])<<24 r1 := uint32(src[4]) | uint32(src[5])<<8 | uint32(src[6])<<16 | uint32(src[7])<<24 r2 := uint32(src[8]) | uint32(src[9])<<8 | uint32(src[10])<<16 | uint32(src[11])<<24 r3 := uint32(src[12]) | uint32(src[13])<<8 | uint32(src[14])<<16 | uint32(src[15])<<24 // Encrypt the block with the 132 sub-keys and 8 S-Boxes r0, r1, r2, r3 = r0^sk[0], r1^sk[1], r2^sk[2], r3^sk[3] sb0(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[4], r1^sk[5], r2^sk[6], r3^sk[7] sb1(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[8], r1^sk[9], r2^sk[10], r3^sk[11] sb2(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[12], r1^sk[13], r2^sk[14], r3^sk[15] sb3(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[16], r1^sk[17], r2^sk[18], r3^sk[19] sb4(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[20], r1^sk[21], r2^sk[22], r3^sk[23] sb5(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[24], r1^sk[25], r2^sk[26], r3^sk[27] sb6(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[28], r1^sk[29], r2^sk[30], r3^sk[31] sb7(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[32], r1^sk[33], r2^sk[34], r3^sk[35] sb0(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[36], r1^sk[37], r2^sk[38], r3^sk[39] sb1(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[40], r1^sk[41], r2^sk[42], r3^sk[43] sb2(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[44], r1^sk[45], r2^sk[46], r3^sk[47] sb3(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[48], r1^sk[49], r2^sk[50], r3^sk[51] sb4(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[52], r1^sk[53], r2^sk[54], r3^sk[55] sb5(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[56], r1^sk[57], r2^sk[58], r3^sk[59] sb6(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[60], r1^sk[61], r2^sk[62], r3^sk[63] sb7(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[64], r1^sk[65], r2^sk[66], r3^sk[67] sb0(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[68], r1^sk[69], r2^sk[70], r3^sk[71] sb1(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[72], r1^sk[73], r2^sk[74], r3^sk[75] sb2(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[76], r1^sk[77], r2^sk[78], r3^sk[79] sb3(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[80], r1^sk[81], r2^sk[82], r3^sk[83] sb4(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[84], r1^sk[85], r2^sk[86], r3^sk[87] sb5(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[88], r1^sk[89], r2^sk[90], r3^sk[91] sb6(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[92], r1^sk[93], r2^sk[94], r3^sk[95] sb7(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[96], r1^sk[97], r2^sk[98], r3^sk[99] sb0(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[100], r1^sk[101], r2^sk[102], r3^sk[103] sb1(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[104], r1^sk[105], r2^sk[106], r3^sk[107] sb2(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[108], r1^sk[109], r2^sk[110], r3^sk[111] sb3(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[112], r1^sk[113], r2^sk[114], r3^sk[115] sb4(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[116], r1^sk[117], r2^sk[118], r3^sk[119] sb5(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[120], r1^sk[121], r2^sk[122], r3^sk[123] sb6(&r0, &r1, &r2, &r3) linear(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[124], r1^sk[125], r2^sk[126], r3^sk[127] sb7(&r0, &r1, &r2, &r3) // whitening r0 ^= sk[128] r1 ^= sk[129] r2 ^= sk[130] r3 ^= sk[131] // write the encrypted block to the output dst[0] = byte(r0) dst[1] = byte(r0 >> 8) dst[2] = byte(r0 >> 16) dst[3] = byte(r0 >> 24) dst[4] = byte(r1) dst[5] = byte(r1 >> 8) dst[6] = byte(r1 >> 16) dst[7] = byte(r1 >> 24) dst[8] = byte(r2) dst[9] = byte(r2 >> 8) dst[10] = byte(r2 >> 16) dst[11] = byte(r2 >> 24) dst[12] = byte(r3) dst[13] = byte(r3 >> 8) dst[14] = byte(r3 >> 16) dst[15] = byte(r3 >> 24) } // Decrypts one block with the given 132 sub-keys sk. func decryptBlock(dst, src []byte, sk *subkeys) { // Transform the input block to 4 x 32 bit registers r0 := uint32(src[0]) | uint32(src[1])<<8 | uint32(src[2])<<16 | uint32(src[3])<<24 r1 := uint32(src[4]) | uint32(src[5])<<8 | uint32(src[6])<<16 | uint32(src[7])<<24 r2 := uint32(src[8]) | uint32(src[9])<<8 | uint32(src[10])<<16 | uint32(src[11])<<24 r3 := uint32(src[12]) | uint32(src[13])<<8 | uint32(src[14])<<16 | uint32(src[15])<<24 // undo whitening r0 ^= sk[128] r1 ^= sk[129] r2 ^= sk[130] r3 ^= sk[131] // Decrypt the block with the 132 sub-keys and 8 S-Boxes sb7Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[124], r1^sk[125], r2^sk[126], r3^sk[127] linearInv(&r0, &r1, &r2, &r3) sb6Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[120], r1^sk[121], r2^sk[122], r3^sk[123] linearInv(&r0, &r1, &r2, &r3) sb5Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[116], r1^sk[117], r2^sk[118], r3^sk[119] linearInv(&r0, &r1, &r2, &r3) sb4Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[112], r1^sk[113], r2^sk[114], r3^sk[115] linearInv(&r0, &r1, &r2, &r3) sb3Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[108], r1^sk[109], r2^sk[110], r3^sk[111] linearInv(&r0, &r1, &r2, &r3) sb2Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[104], r1^sk[105], r2^sk[106], r3^sk[107] linearInv(&r0, &r1, &r2, &r3) sb1Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[100], r1^sk[101], r2^sk[102], r3^sk[103] linearInv(&r0, &r1, &r2, &r3) sb0Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[96], r1^sk[97], r2^sk[98], r3^sk[99] linearInv(&r0, &r1, &r2, &r3) sb7Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[92], r1^sk[93], r2^sk[94], r3^sk[95] linearInv(&r0, &r1, &r2, &r3) sb6Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[88], r1^sk[89], r2^sk[90], r3^sk[91] linearInv(&r0, &r1, &r2, &r3) sb5Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[84], r1^sk[85], r2^sk[86], r3^sk[87] linearInv(&r0, &r1, &r2, &r3) sb4Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[80], r1^sk[81], r2^sk[82], r3^sk[83] linearInv(&r0, &r1, &r2, &r3) sb3Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[76], r1^sk[77], r2^sk[78], r3^sk[79] linearInv(&r0, &r1, &r2, &r3) sb2Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[72], r1^sk[73], r2^sk[74], r3^sk[75] linearInv(&r0, &r1, &r2, &r3) sb1Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[68], r1^sk[69], r2^sk[70], r3^sk[71] linearInv(&r0, &r1, &r2, &r3) sb0Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[64], r1^sk[65], r2^sk[66], r3^sk[67] linearInv(&r0, &r1, &r2, &r3) sb7Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[60], r1^sk[61], r2^sk[62], r3^sk[63] linearInv(&r0, &r1, &r2, &r3) sb6Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[56], r1^sk[57], r2^sk[58], r3^sk[59] linearInv(&r0, &r1, &r2, &r3) sb5Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[52], r1^sk[53], r2^sk[54], r3^sk[55] linearInv(&r0, &r1, &r2, &r3) sb4Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[48], r1^sk[49], r2^sk[50], r3^sk[51] linearInv(&r0, &r1, &r2, &r3) sb3Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[44], r1^sk[45], r2^sk[46], r3^sk[47] linearInv(&r0, &r1, &r2, &r3) sb2Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[40], r1^sk[41], r2^sk[42], r3^sk[43] linearInv(&r0, &r1, &r2, &r3) sb1Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[36], r1^sk[37], r2^sk[38], r3^sk[39] linearInv(&r0, &r1, &r2, &r3) sb0Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[32], r1^sk[33], r2^sk[34], r3^sk[35] linearInv(&r0, &r1, &r2, &r3) sb7Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[28], r1^sk[29], r2^sk[30], r3^sk[31] linearInv(&r0, &r1, &r2, &r3) sb6Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[24], r1^sk[25], r2^sk[26], r3^sk[27] linearInv(&r0, &r1, &r2, &r3) sb5Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[20], r1^sk[21], r2^sk[22], r3^sk[23] linearInv(&r0, &r1, &r2, &r3) sb4Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[16], r1^sk[17], r2^sk[18], r3^sk[19] linearInv(&r0, &r1, &r2, &r3) sb3Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[12], r1^sk[13], r2^sk[14], r3^sk[15] linearInv(&r0, &r1, &r2, &r3) sb2Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[8], r1^sk[9], r2^sk[10], r3^sk[11] linearInv(&r0, &r1, &r2, &r3) sb1Inv(&r0, &r1, &r2, &r3) r0, r1, r2, r3 = r0^sk[4], r1^sk[5], r2^sk[6], r3^sk[7] linearInv(&r0, &r1, &r2, &r3) sb0Inv(&r0, &r1, &r2, &r3) r0 ^= sk[0] r1 ^= sk[1] r2 ^= sk[2] r3 ^= sk[3] // write the decrypted block to the output dst[0] = byte(r0) dst[1] = byte(r0 >> 8) dst[2] = byte(r0 >> 16) dst[3] = byte(r0 >> 24) dst[4] = byte(r1) dst[5] = byte(r1 >> 8) dst[6] = byte(r1 >> 16) dst[7] = byte(r1 >> 24) dst[8] = byte(r2) dst[9] = byte(r2 >> 8) dst[10] = byte(r2 >> 16) dst[11] = byte(r2 >> 24) dst[12] = byte(r3) dst[13] = byte(r3 >> 8) dst[14] = byte(r3 >> 16) dst[15] = byte(r3 >> 24) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/serpent/serpent_test.go000066400000000000000000000157731520706056300262320ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package serpent import ( "bytes" "crypto/cipher" "encoding/hex" "testing" ) var recoverFail = func(t *testing.T) { if err := recover(); err == nil { t.Fatal("Recover expected error, but no one occured") } } var badKeys = [][]byte{ make([]byte, 15), make([]byte, 17), make([]byte, 23), make([]byte, 25), make([]byte, 31), make([]byte, 33), } func TestEncrypt(t *testing.T) { encFail := func(t *testing.T, c cipher.Block, srcLen, dstLen int) { defer recoverFail(t) src := make([]byte, srcLen) dst := make([]byte, dstLen) c.Encrypt(dst, src) } c, err := NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Failed to create serpent cipher: %s", err) } encFail(t, c, BlockSize-1, BlockSize) encFail(t, c, BlockSize, BlockSize-1) } func TestDecrypt(t *testing.T) { decFail := func(t *testing.T, c cipher.Block, srcLen, dstLen int) { defer recoverFail(t) src := make([]byte, srcLen) dst := make([]byte, dstLen) c.Decrypt(dst, src) } c, err := NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Failed to create serpent cipher: %s", err) } decFail(t, c, BlockSize-1, BlockSize) decFail(t, c, BlockSize, BlockSize-1) } func TestEncryptDecrypt(t *testing.T) { c, err := NewCipher(make([]byte, 16)) if err != nil { t.Fatalf("Failed to create serpent cipher: %s", err) } src := make([]byte, 32) dst := make([]byte, 32) c.Encrypt(dst, src) c.Encrypt(dst[16:], src[:16]) c.Decrypt(dst, dst) c.Decrypt(dst[16:], dst[16:]) if !bytes.Equal(src, dst) { t.Fatalf("En / decryption sequence failed\nFound: %s\nExpected: %s", hex.EncodeToString(dst), hex.EncodeToString(src)) } } func TestNewCipher(t *testing.T) { var ( key128 [16]byte key192 [24]byte key256 [32]byte ) _, err := NewCipher(key128[:]) if err != nil { t.Fatalf("NewCipher rejected valid key with length: %d", len(key128)) } _, err = NewCipher(key192[:]) if err != nil { t.Fatalf("NewCipher rejected valid key with length: %d", len(key192)) } _, err = NewCipher(key256[:]) if err != nil { t.Fatalf("NewCipher rejected valid key with length: %d", len(key256)) } for i, v := range badKeys { _, err := NewCipher(v) if err == nil { t.Fatalf("NewCipher accpeted bad key %d with length: %d", i, len(v)) } } } func TestBlockSize(t *testing.T) { s := new(subkeys) if bs := s.BlockSize(); bs != BlockSize { t.Fatalf("BlockSize() returned unexpected value: %d", bs) } } // Tests the S-Box 0 and its inverse. func TestSBox0(t *testing.T) { v0, v1, v2, v3 := uint32(0), uint32(0), uint32(0), uint32(0) for i := 0; i < 16; i++ { v0, v1, v2, v3 = v3+v0+uint32(i), v0+v1, v1+v2, v2+v3 i0, i1, i2, i3 := v0, v1, v2, v3 sb0(&v0, &v1, &v2, &v3) sb0Inv(&v0, &v1, &v2, &v3) if i0 != v0 || i1 != v1 || i2 != v2 || i3 != v3 { t.Fatal("Sbox 0 failed") } } } // Tests the S-Box 1 and its inverse. func TestSBox1(t *testing.T) { v0, v1, v2, v3 := uint32(0), uint32(0), uint32(0), uint32(0) for i := 0; i < 16; i++ { v0, v1, v2, v3 = v3+v0+uint32(i), v0+v1, v1+v2, v2+v3 i0, i1, i2, i3 := v0, v1, v2, v3 sb1(&v0, &v1, &v2, &v3) sb1Inv(&v0, &v1, &v2, &v3) if i0 != v0 || i1 != v1 || i2 != v2 || i3 != v3 { t.Fatal("sbox 1 failed") } } } // Tests the S-Box 2 and its inverse. func TestSBox2(t *testing.T) { v0, v1, v2, v3 := uint32(0), uint32(0), uint32(0), uint32(0) for i := 0; i < 16; i++ { v0, v1, v2, v3 = v3+v0+uint32(i), v0+v1, v1+v2, v2+v3 i0, i1, i2, i3 := v0, v1, v2, v3 sb2(&v0, &v1, &v2, &v3) sb2Inv(&v0, &v1, &v2, &v3) if i0 != v0 || i1 != v1 || i2 != v2 || i3 != v3 { t.Fatal("sbox 2 failed") } } } // Tests the S-Box 3 and its inverse. func TestSBox3(t *testing.T) { v0, v1, v2, v3 := uint32(0), uint32(0), uint32(0), uint32(0) for i := 0; i < 16; i++ { v0, v1, v2, v3 = v3+v0+uint32(i), v0+v1, v1+v2, v2+v3 i0, i1, i2, i3 := v0, v1, v2, v3 sb3(&v0, &v1, &v2, &v3) sb3Inv(&v0, &v1, &v2, &v3) if i0 != v0 || i1 != v1 || i2 != v2 || i3 != v3 { t.Fatal("sbox 3 failed") } } } // Tests the S-Box 4 and its inverse. func TestSBox4(t *testing.T) { v0, v1, v2, v3 := uint32(0), uint32(0), uint32(0), uint32(0) for i := 0; i < 16; i++ { v0, v1, v2, v3 = v3+v0+uint32(i), v0+v1, v1+v2, v2+v3 i0, i1, i2, i3 := v0, v1, v2, v3 sb4(&v0, &v1, &v2, &v3) sb4Inv(&v0, &v1, &v2, &v3) if i0 != v0 || i1 != v1 || i2 != v2 || i3 != v3 { t.Fatal("sbox 4 failed") } } } // Tests the S-Box 5 and its inverse. func TestSBox5(t *testing.T) { v0, v1, v2, v3 := uint32(0), uint32(0), uint32(0), uint32(0) for i := 0; i < 16; i++ { v0, v1, v2, v3 = v3+v0+uint32(i), v0+v1, v1+v2, v2+v3 i0, i1, i2, i3 := v0, v1, v2, v3 sb5(&v0, &v1, &v2, &v3) sb5Inv(&v0, &v1, &v2, &v3) if i0 != v0 || i1 != v1 || i2 != v2 || i3 != v3 { t.Fatal("sbox 5 failed") } } } // Tests the S-Box 6 and its inverse. func TestSBox6(t *testing.T) { v0, v1, v2, v3 := uint32(0), uint32(0), uint32(0), uint32(0) for i := 0; i < 16; i++ { v0, v1, v2, v3 = v3+v0+uint32(i), v0+v1, v1+v2, v2+v3 i0, i1, i2, i3 := v0, v1, v2, v3 sb6(&v0, &v1, &v2, &v3) sb6Inv(&v0, &v1, &v2, &v3) if i0 != v0 || i1 != v1 || i2 != v2 || i3 != v3 { t.Fatal("sbox 6 failed") } } } // Tests the S-Box 7 and its inverse. func TestSBox7(t *testing.T) { v0, v1, v2, v3 := uint32(0), uint32(0), uint32(0), uint32(0) for i := 0; i < 16; i++ { v0, v1, v2, v3 = v3+v0+uint32(i), v0+v1, v1+v2, v2+v3 i0, i1, i2, i3 := v0, v1, v2, v3 sb7(&v0, &v1, &v2, &v3) sb7Inv(&v0, &v1, &v2, &v3) if i0 != v0 || i1 != v1 || i2 != v2 || i3 != v3 { t.Fatal("sbox 7 failed") } } } // Tests the linear transformation and its inverse func TestLinear(t *testing.T) { v0, v1, v2, v3 := uint32(0), uint32(0), uint32(0), uint32(0) for i := 0; i < 16; i++ { v0, v1, v2, v3 = v3+v0+uint32(i), v0+v1, v1+v2, v2+v3 i0, i1, i2, i3 := v0, v1, v2, v3 linear(&v0, &v1, &v2, &v3) linearInv(&v0, &v1, &v2, &v3) if i0 != v0 || i1 != v1 || i2 != v2 || i3 != v3 { t.Fatal("linear function failed") } } } // Benchmarks func BenchmarkEncrypt_16(b *testing.B) { benchmarkEncrypt(b, 16) } func BenchmarkDecrypt_16(b *testing.B) { benchmarkDecrypt(b, 16) } func BenchmarkEncrypt_1K(b *testing.B) { benchmarkEncrypt(b, 1024) } func BenchmarkDecrypt_1K(b *testing.B) { benchmarkDecrypt(b, 1024) } func benchmarkEncrypt(b *testing.B, size int) { c, err := NewCipher(make([]byte, 16)) if err != nil { b.Fatalf("Failed to create Serpent instance: %s", err) } buf := make([]byte, c.BlockSize()) b.SetBytes(int64(size - (size % c.BlockSize()))) n := size / c.BlockSize() b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < n; j++ { c.Encrypt(buf, buf) } } } func benchmarkDecrypt(b *testing.B, size int) { c, err := NewCipher(make([]byte, 16)) if err != nil { b.Fatalf("Failed to create Serpent instance: %s", err) } buf := make([]byte, c.BlockSize()) b.SetBytes(int64(size - (size % c.BlockSize()))) n := size / c.BlockSize() b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < n; j++ { c.Decrypt(buf, buf) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/serpent/vectors_test.go000066400000000000000000000052011520706056300262200ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package serpent import ( "bytes" "encoding/hex" "testing" ) func fromHex(s string) []byte { b, err := hex.DecodeString(s) if err != nil { panic(err) } return b } // Test vectors for serpent var vectors = []struct { key, plaintext, ciphertext string }{ // test vectors for 128 bit key from // http://www.cs.technion.ac.il/~biham/Reports/Serpent/Serpent-128-128.verified.test-vectors { // Set 1, vector# 0 key: "80000000000000000000000000000000", plaintext: "00000000000000000000000000000000", ciphertext: "264E5481EFF42A4606ABDA06C0BFDA3D", }, { // Set 1, vector# 1 key: "40000000000000000000000000000000", plaintext: "00000000000000000000000000000000", ciphertext: "4A231B3BC727993407AC6EC8350E8524", }, // test vectors for 192 bit key from // http://www.cs.technion.ac.il/~biham/Reports/Serpent/Serpent-192-128.verified.test-vectors { // Set 1, vector# 0 key: "800000000000000000000000000000000000000000000000", plaintext: "00000000000000000000000000000000", ciphertext: "9E274EAD9B737BB21EFCFCA548602689", }, { // Set 1, vector# 3 key: "100000000000000000000000000000000000000000000000", plaintext: "00000000000000000000000000000000", ciphertext: "BEC1E37824CF721E5D87F6CB4EBFB9BE", }, // test vectors for 256 bit key from // http://www.cs.technion.ac.il/~biham/Reports/Serpent/Serpent-256-128.verified.test-vectors { // Set 3, vector# 1 key: "0101010101010101010101010101010101010101010101010101010101010101", plaintext: "01010101010101010101010101010101", ciphertext: "EC9723B15B2A6489F84C4524FFFC2748", }, { // Set 3, vector# 2 key: "0202020202020202020202020202020202020202020202020202020202020202", plaintext: "02020202020202020202020202020202", ciphertext: "1187F485538514476184E567DA0421C7", }, } // Tests all serpent test vectors. func TestVectors(t *testing.T) { for i, v := range vectors { key := fromHex(v.key) plaintext := fromHex(v.plaintext) ciphertext := fromHex(v.ciphertext) c, err := NewCipher(key) if err != nil { t.Fatalf("Test vector %d: Failed to create cipher instance: %s", i, err) } buf := make([]byte, BlockSize) c.Encrypt(buf, plaintext) if !bytes.Equal(ciphertext, buf) { t.Fatalf("Test vector %d:\nEncryption failed\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(ciphertext)) } c.Decrypt(buf, buf) if !bytes.Equal(plaintext, buf) { t.Fatalf("Test vector %d:\nDecryption failed\nFound: %s\nExpected: %s", i, hex.EncodeToString(buf), hex.EncodeToString(plaintext)) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/siphash/000077500000000000000000000000001520706056300231265ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/siphash/siphash.go000066400000000000000000000050141520706056300251140ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // Package siphash implements a hash / MAC function // developed Jean-Philippe Aumasson and Daniel J Bernstein // in 2012. SipHash computes 64-bit message authentication // code from a variable-length message and a 128-bit secret // key. It was designed to be efficient even for short inputs, // with performance comparable to non-cryptographic hash // functions. This package implements SipHash with the // recommended parameters: c = 2 and d = 4. package siphash import "crypto/subtle" // The size of the SipHash authentication tag in bytes. const TagSize = 8 // The four initialization constants const ( c0 = uint64(0x736f6d6570736575) c1 = uint64(0x646f72616e646f6d) c2 = uint64(0x6c7967656e657261) c3 = uint64(0x7465646279746573) ) // Verify checks whether the given sum is equal to the // computed checksum of msg. This function returns true // if and only if the computed checksum is equal to the // given sum. func Verify(sum *[TagSize]byte, msg []byte, key *[16]byte) bool { var out [TagSize]byte Sum(&out, msg, key) return subtle.ConstantTimeCompare(sum[:], out[:]) == 1 } // The siphash hash struct implementing hash.Hash type hashFunc struct { hVal [4]uint64 key [2]uint64 block [TagSize]byte off int ctr byte } func (h *hashFunc) BlockSize() int { return TagSize } func (h *hashFunc) Size() int { return TagSize } func (h *hashFunc) Reset() { h.hVal[0] = h.key[0] ^ c0 h.hVal[1] = h.key[1] ^ c1 h.hVal[2] = h.key[0] ^ c2 h.hVal[3] = h.key[1] ^ c3 h.off = 0 h.ctr = 0 } func (h *hashFunc) Write(p []byte) (int, error) { n := len(p) h.ctr += byte(n) if h.off > 0 { dif := TagSize - h.off if n > dif { h.off += copy(h.block[h.off:], p[:dif]) p = p[dif:] core(&(h.hVal), h.block[:]) h.off = 0 } else { h.off += copy(h.block[h.off:], p) return n, nil } } if nn := len(p); nn >= TagSize { nn &= (^(TagSize - 1)) core(&(h.hVal), p[:nn]) p = p[nn:] } if len(p) > 0 { h.off = copy(h.block[:], p) } return n, nil } func (h *hashFunc) Sum64() uint64 { hVal := h.hVal block := h.block for i := h.off; i < TagSize-1; i++ { block[i] = 0 } block[7] = h.ctr return finalize(&hVal, &block) } func (h *hashFunc) Sum(b []byte) []byte { r := h.Sum64() var out [TagSize]byte out[0] = byte(r) out[1] = byte(r >> 8) out[2] = byte(r >> 16) out[3] = byte(r >> 24) out[4] = byte(r >> 32) out[5] = byte(r >> 40) out[6] = byte(r >> 48) out[7] = byte(r >> 56) return append(b, out[:]...) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/siphash/siphash_amd64.go000066400000000000000000000004251520706056300261100ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build amd64, !appengine, !gccgo package siphash //go:noescape func core(hVal *[4]uint64, msg []byte) //go:noescape func finalize(hVal *[4]uint64, block *[TagSize]byte) uint64 golang-github-enceve-crypto-0.0~git20160707.34d48bb/siphash/siphash_amd64.s000066400000000000000000000025161520706056300257500ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build amd64,!appengine,!gccgo #define ROUND(v0, v1, v2, v3) \ ADDQ v1, v0; \ RORQ $51, v1; \ ADDQ v3, v2; \ XORQ v0, v1; \ RORQ $48, v3; \ RORQ $32, v0; \ XORQ v2, v3; \ ADDQ v1, v2; \ ADDQ v3, v0; \ RORQ $43, v3; \ RORQ $47, v1; \ XORQ v0, v3; \ XORQ v2, v1; \ RORQ $32, v2 // core(hVal *[4]uint64, msg []byte) TEXT ·core(SB),4,$0-32 MOVQ hVal+0(FP), AX MOVQ msg+16(FP), BX MOVQ msg+8(FP), CX MOVQ 0(AX), R9 MOVQ 8(AX), R10 MOVQ 16(AX), R11 MOVQ 24(AX), R12 ANDQ $0XFFFFFFFFFFFFFFF8, BX // BX & (^7) loop: MOVQ 0(CX), DX XORQ DX, R12 ROUND(R9, R10, R11, R12) ROUND(R9, R10, R11, R12) XORQ DX, R9 ADDQ $8, CX SUBQ $8, BX JNZ loop MOVQ R9, 0(AX) MOVQ R10, 8(AX) MOVQ R11, 16(AX) MOVQ R12, 24(AX) RET // finalize(hVal *[4]uint64, block *[8]byte) uint64 TEXT ·finalize(SB),4,$0-24 MOVQ hVal+0(FP), AX MOVQ block+8(FP), BX MOVQ 0(BX), CX MOVQ 0(AX), R9 MOVQ 8(AX), R10 MOVQ 16(AX), R11 MOVQ 24(AX), R12 XORQ CX, R12 ROUND(R9, R10, R11, R12) ROUND(R9, R10, R11, R12) XORQ CX, R9 NOTB R11 ROUND(R9, R10, R11, R12) ROUND(R9, R10, R11, R12) ROUND(R9, R10, R11, R12) ROUND(R9, R10, R11, R12) XORQ R12, R11 XORQ R10, R9 XORQ R11, R9 MOVQ R9, ret+16(FP) RET golang-github-enceve-crypto-0.0~git20160707.34d48bb/siphash/siphash_ref.go000066400000000000000000000044121520706056300257510ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build !amd64 appengine gccgo package siphash func finalize(hVal *[4]uint64, block *[TagSize]byte) uint64 { core(hVal, block[:]) v0, v1, v2, v3 := hVal[0], hVal[1], hVal[2], hVal[3] v2 ^= 0xff // Round 1. v0 += v1 v1 = v1<<13 | v1>>(64-13) v1 ^= v0 v0 = v0<<32 | v0>>(64-32) v2 += v3 v3 = v3<<16 | v3>>(64-16) v3 ^= v2 v0 += v3 v3 = v3<<21 | v3>>(64-21) v3 ^= v0 v2 += v1 v1 = v1<<17 | v1>>(64-17) v1 ^= v2 v2 = v2<<32 | v2>>(64-32) // Round 2. v0 += v1 v1 = v1<<13 | v1>>(64-13) v1 ^= v0 v0 = v0<<32 | v0>>(64-32) v2 += v3 v3 = v3<<16 | v3>>(64-16) v3 ^= v2 v0 += v3 v3 = v3<<21 | v3>>(64-21) v3 ^= v0 v2 += v1 v1 = v1<<17 | v1>>(64-17) v1 ^= v2 v2 = v2<<32 | v2>>(64-32) // Round 3. v0 += v1 v1 = v1<<13 | v1>>(64-13) v1 ^= v0 v0 = v0<<32 | v0>>(64-32) v2 += v3 v3 = v3<<16 | v3>>(64-16) v3 ^= v2 v0 += v3 v3 = v3<<21 | v3>>(64-21) v3 ^= v0 v2 += v1 v1 = v1<<17 | v1>>(64-17) v1 ^= v2 v2 = v2<<32 | v2>>(64-32) // Round 4. v0 += v1 v1 = v1<<13 | v1>>(64-13) v1 ^= v0 v0 = v0<<32 | v0>>(64-32) v2 += v3 v3 = v3<<16 | v3>>(64-16) v3 ^= v2 v0 += v3 v3 = v3<<21 | v3>>(64-21) v3 ^= v0 v2 += v1 v1 = v1<<17 | v1>>(64-17) v1 ^= v2 v2 = v2<<32 | v2>>(64-32) return v0 ^ v1 ^ v2 ^ v3 } func core(hVal *[4]uint64, msg []byte) { v0, v1, v2, v3 := hVal[0], hVal[1], hVal[2], hVal[3] for i := 0; i < len(msg); i += TagSize { m := uint64(msg[i]) | uint64(msg[i+1])<<8 | uint64(msg[i+2])<<16 | uint64(msg[i+3])<<24 | uint64(msg[i+4])<<32 | uint64(msg[i+5])<<40 | uint64(msg[i+6])<<48 | uint64(msg[i+7])<<56 v3 ^= m // Round 1. v0 += v1 v1 = v1<<13 | v1>>(64-13) v1 ^= v0 v0 = v0<<32 | v0>>(64-32) v2 += v3 v3 = v3<<16 | v3>>(64-16) v3 ^= v2 v0 += v3 v3 = v3<<21 | v3>>(64-21) v3 ^= v0 v2 += v1 v1 = v1<<17 | v1>>(64-17) v1 ^= v2 v2 = v2<<32 | v2>>(64-32) // Round 2. v0 += v1 v1 = v1<<13 | v1>>(64-13) v1 ^= v0 v0 = v0<<32 | v0>>(64-32) v2 += v3 v3 = v3<<16 | v3>>(64-16) v3 ^= v2 v0 += v3 v3 = v3<<21 | v3>>(64-21) v3 ^= v0 v2 += v1 v1 = v1<<17 | v1>>(64-17) v1 ^= v2 v2 = v2<<32 | v2>>(64-32) v0 ^= m } hVal[0], hVal[1], hVal[2], hVal[3] = v0, v1, v2, v3 } golang-github-enceve-crypto-0.0~git20160707.34d48bb/siphash/siphash_test.go000066400000000000000000000073711520706056300261630ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package siphash import ( "bytes" "encoding/hex" "testing" "unsafe" ) func TestBlockSize(t *testing.T) { var key [16]byte h := New(&key) if bs := h.BlockSize(); bs != 8 { t.Fatalf("BlockSize() returned: %d - but expected: %d", bs, 8) } } func TestSize(t *testing.T) { var key [16]byte h := New(&key) if bs := h.Size(); bs != 8 { t.Fatalf("Size() returned: %d - but expected: %d", bs, 8) } } func TestReset(t *testing.T) { var key [16]byte h := New(&key) s, ok := h.(*hashFunc) if !ok { t.Fatal("Impossible situation: New returns no siphash struct") } orig := *s // copy s.Write(make([]byte, 18)) s.Reset() if s.hVal != orig.hVal { t.Fatalf("Reseted hVal field: %d - but expected: %d", s.block, orig.block) } if s.block != orig.block { t.Fatalf("Reseted block field: %d - but expected: %d", s.block, orig.block) } if s.ctr != orig.ctr { t.Fatalf("Reseted ctr field: %v - but expected: %v", s.ctr, orig.ctr) } if s.key != orig.key { t.Fatalf("Reseted key field: %v - but expected: %v", s.key, orig.key) } if s.off != orig.off { t.Fatalf("Reseted off field %v - but expected %v", s.off, orig.off) } } func TestWrite(t *testing.T) { var key [16]byte for i := range key { key[i] = byte(i) } h := New(&key) var msg1 []byte msg0 := make([]byte, 64) for i := range msg0 { h.Write(msg0[:i]) msg1 = append(msg1, msg0[:i]...) } if tag0, tag1 := h.Sum64(), Sum64(msg1, &key); tag0 != tag1 { t.Fatalf("Sum64 differ from siphash.Sum64\n Sum64: %x \n siphash.Sum64: %x", tag0, tag1) } } func TestSum(t *testing.T) { var key [16]byte for i := range key { key[i] = byte(i) } h := New(&key) msg := make([]byte, 64) var tag [8]byte for i := range msg { h.Write(msg[:i]) sum := h.Sum(nil) h.Reset() Sum(&tag, msg[:i], &key) if !bytes.Equal(sum, tag[:]) { t.Fatalf("Iteration %d: Sum differ from siphash.Sum\n Sum: %s \n sipash.Sum %s", i, hex.EncodeToString(sum), hex.EncodeToString(tag[:])) } } } func TestVerify(t *testing.T) { var key [16]byte for i := range key { key[i] = byte(i) } h := New(&key) msg := make([]byte, 64) var tag [8]byte for i := range msg { h.Write(msg[:i]) h.Sum(tag[:0]) h.Reset() if !Verify(&tag, msg[:i], &key) { t.Fatalf("Iteration %d: Verify failed: %s not accepted ", i, hex.EncodeToString(tag[:])) } } } // Benchmarks func BenchmarkWrite_8(b *testing.B) { benchmarkWrite(b, 8, false) } func BenchmarkWriteUnaligned_8(b *testing.B) { benchmarkWrite(b, 8, true) } func BenchmarkWrite_1K(b *testing.B) { benchmarkWrite(b, 1024, false) } func BenchmarkWriteUnaligned_1K(b *testing.B) { benchmarkWrite(b, 1024, true) } func BenchmarkSum_8(b *testing.B) { benchmarkWrite(b, 8, false) } func BenchmarkSumUnaligned_8(b *testing.B) { benchmarkWrite(b, 8, true) } func BenchmarkSum_1K(b *testing.B) { benchmarkWrite(b, 1024, false) } func BenchmarkSumUnaligned_1K(b *testing.B) { benchmarkWrite(b, 1024, true) } func unalignBytes(in []byte) []byte { out := make([]byte, len(in)+1) if uintptr(unsafe.Pointer(&out[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { out = out[1:] } else { out = out[:len(in)] } copy(out, in) return out } func benchmarkWrite(b *testing.B, size int, unalign bool) { var key [16]byte h := New(&key) msg := make([]byte, size) if unalign { msg = unalignBytes(msg) } b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { h.Write(msg) } } func benchmarkSum(b *testing.B, size int, unalign bool) { var out [TagSize]byte var key [16]byte msg := make([]byte, size) if unalign { msg = unalignBytes(msg) } b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { Sum(&out, msg, &key) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/siphash/sum_amd64.go000066400000000000000000000022741520706056300252610ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build amd64, !cgo, !appengine package siphash import ( "hash" "unsafe" ) // New returns a hash.Hash64 computing the SipHash checksum with a 128 bit key. func New(key *[16]byte) hash.Hash64 { h := new(hashFunc) h.key[0] = *(*uint64)(unsafe.Pointer(&key[0])) h.key[1] = *(*uint64)(unsafe.Pointer(&key[8])) h.Reset() return h } // Sum generates an authenticator for msg with a 128 bit key // and puts the 64 bit result into out. func Sum(out *[TagSize]byte, msg []byte, key *[16]byte) { (*[1]uint64)(unsafe.Pointer(&out[0]))[0] = Sum64(msg, key) } // Sum64 generates and returns the 64 bit authenticator // for msg with a 128 bit key. func Sum64(msg []byte, key *[16]byte) uint64 { k0 := *(*uint64)(unsafe.Pointer(&key[0])) k1 := *(*uint64)(unsafe.Pointer(&key[8])) var hVal [4]uint64 hVal[0] = k0 ^ c0 hVal[1] = k1 ^ c1 hVal[2] = k0 ^ c2 hVal[3] = k1 ^ c3 n := len(msg) ctr := byte(n) if n >= TagSize { n &= (^(TagSize - 1)) core(&hVal, msg[:n]) msg = msg[n:] } var block [TagSize]byte for i, v := range msg { block[i] = v } block[7] = ctr return finalize(&hVal, &block) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/siphash/sum_ref.go000066400000000000000000000033311520706056300251150ustar00rootroot00000000000000// +build !amd64 package siphash import "hash" // New returns a hash.Hash64 computing the SipHash checksum with a 128 bit key. func New(key *[16]byte) hash.Hash64 { h := new(hashFunc) h.key[0] = uint64(key[0]) | uint64(key[1])<<8 | uint64(key[2])<<16 | uint64(key[3])<<24 | uint64(key[4])<<32 | uint64(key[5])<<40 | uint64(key[6])<<48 | uint64(key[7])<<56 h.key[1] = uint64(key[8]) | uint64(key[9])<<8 | uint64(key[10])<<16 | uint64(key[11])<<24 | uint64(key[12])<<32 | uint64(key[13])<<40 | uint64(key[14])<<48 | uint64(key[15])<<56 h.Reset() return h } // Sum generates an authenticator for msg with a 128 bit key // and puts the 64 bit result into out. func Sum(out *[TagSize]byte, msg []byte, key *[16]byte) { r := Sum64(msg, key) out[0] = byte(r) out[1] = byte(r >> 8) out[2] = byte(r >> 16) out[3] = byte(r >> 24) out[4] = byte(r >> 32) out[5] = byte(r >> 40) out[6] = byte(r >> 48) out[7] = byte(r >> 56) } // Sum64 generates and returns the 64 bit authenticator // for msg with a 128 bit key. func Sum64(msg []byte, key *[16]byte) uint64 { k0 := uint64(key[0]) | uint64(key[1])<<8 | uint64(key[2])<<16 | uint64(key[3])<<24 | uint64(key[4])<<32 | uint64(key[5])<<40 | uint64(key[6])<<48 | uint64(key[7])<<56 k1 := uint64(key[8]) | uint64(key[9])<<8 | uint64(key[10])<<16 | uint64(key[11])<<24 | uint64(key[12])<<32 | uint64(key[13])<<40 | uint64(key[14])<<48 | uint64(key[15])<<56 var hVal [4]uint64 hVal[0] = k0 ^ c0 hVal[1] = k1 ^ c1 hVal[2] = k0 ^ c2 hVal[3] = k1 ^ c3 n := len(msg) ctr := byte(n) if n >= TagSize { n &= (^(TagSize - 1)) core(&hVal, msg[:n]) msg = msg[n:] } var block [TagSize]byte for i, v := range msg { block[i] = v } block[7] = ctr return finalize(&hVal, &block) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/siphash/vectors_test.go000066400000000000000000000024641520706056300262070ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. package siphash import ( "encoding/hex" "testing" ) type testVector struct { key, msg string hash uint64 } var vectors []testVector = []testVector{ // Test vector from https://131002.net/siphash/siphash.pdf testVector{ key: "000102030405060708090a0b0c0d0e0f", msg: "000102030405060708090a0b0c0d0e", hash: uint64(0xa129ca6149be45e5), }, } // Tests the SipHash implementation func TestVectors(t *testing.T) { for i, v := range vectors { var key [16]byte k, err := hex.DecodeString(v.key) if err != nil { t.Fatalf("Test vector %d: Failed to decode hex key: %s", i, err) } copy(key[:], k) msg, err := hex.DecodeString(v.msg) if err != nil { t.Fatalf("Test vector %d: Failed to decode hex msg: %s", i, err) } h := New(&key) _, err = h.Write(msg) if err != nil { t.Fatalf("Test vector %d: Spihash write failed: %s", i, err) } sum := h.Sum64() if sum != v.hash { t.Fatalf("Test vector %d: Hash values don't match - found %x expected %x", i, sum, v.hash) } sum = Sum64(msg, &key) if err != nil { t.Fatalf("Test vector %d: Failed to calculate MAC: %s", i, err) } if sum != v.hash { t.Fatalf("Hash values don't match - found %x expected %x", sum, v.hash) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/000077500000000000000000000000001520706056300226005ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/constants.go000066400000000000000000000035701520706056300251500ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package skein import "github.com/enceve/crypto/skein/threefish" const ( // The blocksize of Skein-512 in bytes. BlockSize = threefish.BlockSize512 ) // The different parameter types const ( // CfgKey is the config type for the Key. CfgKey uint64 = 0 // CfgConfig is the config type for the configuration. CfgConfig uint64 = 4 // CfgPersonal is the config type for the personalization. CfgPersonal uint64 = 8 // CfgPublicKey is the config type for the public key. CfgPublicKey uint64 = 12 // CfgKeyID is the config type for the key id. CfgKeyID uint64 = 16 // CfgNonce is the config type for the nonce. CfgNonce uint64 = 20 // CfgMessage is the config type for the message. CfgMessage uint64 = 48 // CfgOutput is the config type for the output. CfgOutput uint64 = 63 // FirstBlock is the first block flag FirstBlock uint64 = 1 << 62 // FinalBlock is the final block flag FinalBlock uint64 = 1 << 63 // The skein schema ID = S H A 3 1 0 0 0 SchemaID uint64 = 0x133414853 ) // Precomputed chain values for Skein-512 var iv160 = [9]uint64{ 0x28B81A2AE013BD91, 0xC2F11668B5BDF78F, 0x1760D8F3F6A56F12, 0x4FB747588239904F, 0x21EDE07F7EAF5056, 0xD908922E63ED70B8, 0xB8EC76FFECCB52FA, 0x01A47BB8A3F27A6E, 0, } var iv256 = [9]uint64{ 0xCCD044A12FDB3E13, 0xE83590301A79A9EB, 0x55AEA0614F816E6F, 0x2A2767A4AE9B94DB, 0xEC06025E74DD7683, 0xE7A436CDC4746251, 0xC36FBAF9393AD185, 0x3EEDBA1833EDFC13, 0, } var iv384 = [9]uint64{ 0xA3F6C6BF3A75EF5F, 0xB0FEF9CCFD84FAA4, 0x9D77DD663D770CFE, 0xD798CBF3B468FDDA, 0x1BC4A6668A0E4465, 0x7ED7D434E5807407, 0x548FC1ACD4EC44D6, 0x266E17546AA18FF8, 0, } var iv512 = [9]uint64{ 0x4903ADFF749C51CE, 0x0D95DE399746DF03, 0x8FD1934127C79BCE, 0x9A255629FF352CB1, 0x5DB62599DF6CA7B0, 0xEABE394CA9D5C3F4, 0x991112C71A75B523, 0xAE18A40B660FCC33, 0, } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein.go000066400000000000000000000124441520706056300242450ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // Package skein implements the Skein512 hash function // based on the Threefish tweakable block cipher. // // // Overview // // Skein is a hash function family using the tweakable block cipher // Threefish in Unique Block Iteration (UBI) chaining mode while // leveraging an optional low-overhead argument-system // for flexibility. There are three versions of Skein, each of them // using the corresponding Threefish version: // - Skein256 using Threefish256 and processes 256 bit blocks // - Skein512 using Threefish512 and processes 512 bit blocks // - Skein1024 using Threefish1024 and processes 1024 bit blocks // // Skein can be used as hash function, MAC or KDF and supports personalized, // randomized (salted) and public-key-bound hashing. Furthermore Skein // has some additional features (currently) not implemented here. For // details see http://www.skein-hash.info/ // Skein was submitted to the SHA-3 challenge. // // Skein can produce hash values of any size (up to (2^64 -1) x BlockSize bytes) // not only the common sizes 160, 224, 256, 384 and 512 bit. // // // Security and Recommendations // // All Skein varaiants (as far as known) secure. The Skein authors recommend to use // Skein512 for most applications. Skein256 should be used for small devices // like smartcards. Skein1024 is the ultra-conservative variant providing a level of // security (mostly) not needed. package skein import ( "hash" ) // Config contains the Skein configuration: // - Key for computing MACs // - Personal for personalized hashing // - PublicKey for public-key-bound hashing // - KeyID for key derivation // - Nonce for randomized hashing // All fields are optional and can be nil. type Config struct { Key []byte // Optional: The secret key for MAC Personal []byte // Optional: The personalization for unique hashing PublicKey []byte // Optional: The public key for public-key bound hashing KeyID []byte // Optional: The key id for key derivation Nonce []byte // Optional: The nonce for randomized hashing } // Sum512 computes the 512 bit Skein512 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum512(out *[64]byte, msg, key []byte) { s := new(hashFunc) if len(key) > 0 { s.initialize(64, &Config{Key: key}) } else { s.hVal = iv512 s.hValCpy = iv512 s.hashsize = BlockSize s.tweak[0] = 0 s.tweak[1] = CfgMessage<<56 | FirstBlock } s.Write(msg) s.finalizeHash() s.output(out, 0) } // Sum384 computes the 384 bit Skein512 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum384(out *[48]byte, msg, key []byte) { var out512 [64]byte s := new(hashFunc) if len(key) > 0 { s.initialize(48, &Config{Key: key}) } else { s.hVal = iv384 s.hValCpy = iv384 s.hashsize = 48 s.tweak[0] = 0 s.tweak[1] = CfgMessage<<56 | FirstBlock } s.Write(msg) s.finalizeHash() s.output(&out512, 0) copy(out[:], out512[:48]) } // Sum256 computes the 256 bit Skein512 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum256(out *[32]byte, msg, key []byte) { var out512 [64]byte s := new(hashFunc) if len(key) > 0 { s.initialize(32, &Config{Key: key}) } else { s.hVal = iv256 s.hValCpy = iv256 s.hashsize = 32 s.tweak[0] = 0 s.tweak[1] = CfgMessage<<56 | FirstBlock } s.Write(msg) s.finalizeHash() s.output(&out512, 0) copy(out[:], out512[:32]) } // Sum160 computes the 160 bit Skein512 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum160(out *[20]byte, msg, key []byte) { var out512 [64]byte s := new(hashFunc) if len(key) > 0 { s.initialize(20, &Config{Key: key}) } else { s.hVal = iv160 s.hValCpy = iv160 s.hashsize = 20 s.tweak[0] = 0 s.tweak[1] = CfgMessage<<56 | FirstBlock } s.Write(msg) s.finalizeHash() s.output(&out512, 0) copy(out[:], out512[:20]) } // Sum returns the Skein512 checksum with the given hash size of msg using the (optional) // conf for configuration. The hashsize must be > 0. func Sum(msg []byte, hashsize int, conf *Config) []byte { s := New(hashsize, conf) s.Write(msg) return s.Sum(nil) } // New512 returns a hash.Hash computing the Skein512 512 bit checksum. // The key is optional and turns the hash into a MAC. func New512(key []byte) hash.Hash { s := new(hashFunc) if len(key) > 0 { s.initialize(BlockSize, &Config{Key: key}) } else { copy(s.hVal[:8], iv512[:]) s.hValCpy = s.hVal s.hashsize = BlockSize s.tweak[0] = 0 s.tweak[1] = CfgMessage<<56 | FirstBlock } return s } // New256 returns a hash.Hash computing the Skein512 256 bit checksum. // The key is optional and turns the hash into a MAC. func New256(key []byte) hash.Hash { s := new(hashFunc) if len(key) > 0 { s.initialize(32, &Config{Key: key}) } else { copy(s.hVal[:8], iv256[:]) s.hValCpy = s.hVal s.hashsize = 32 s.tweak[0] = 0 s.tweak[1] = CfgMessage<<56 | FirstBlock } return s } // New returns a hash.Hash computing the Skein512 checksum with the given hash size. // The conf is optional and configurates the hash.Hash func New(hashsize int, conf *Config) hash.Hash { s := new(hashFunc) s.initialize(hashsize, conf) return s } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein1024/000077500000000000000000000000001520706056300242205ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein1024/skein.go000066400000000000000000000052661520706056300256710ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // Package skein1024 implements the Skein1024 hash function // based on the Threefish1024 tweakable block cipher. package skein1024 import ( "hash" "github.com/enceve/crypto/skein" ) // Sum512 computes the 512 bit Skein1024 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum512(out *[64]byte, msg, key []byte) { var out1024 [128]byte s := new(hashFunc) s.initialize(64, &skein.Config{Key: key}) s.Write(msg) s.finalizeHash() s.output(&out1024, 0) copy(out[:], out1024[:64]) } // Sum384 computes the 384 bit Skein1024 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum384(out *[48]byte, msg, key []byte) { var out1024 [128]byte s := new(hashFunc) s.initialize(48, &skein.Config{Key: key}) s.Write(msg) s.finalizeHash() s.output(&out1024, 0) copy(out[:], out1024[:48]) } // Sum256 computes the 256 bit Skein1024 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum256(out *[32]byte, msg, key []byte) { var out1024 [128]byte s := new(hashFunc) s.initialize(32, &skein.Config{Key: key}) s.Write(msg) s.finalizeHash() s.output(&out1024, 0) copy(out[:], out1024[:32]) } // Sum160 computes the 160 bit Skein1024 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum160(out *[20]byte, msg, key []byte) { var out1024 [128]byte s := new(hashFunc) s.initialize(20, &skein.Config{Key: key}) s.Write(msg) s.finalizeHash() s.output(&out1024, 0) copy(out[:], out1024[:20]) } // Sum returns the Skein1024 checksum with the given hash size of msg using the (optional) // conf for configuration. The hashsize must be > 0. func Sum(msg []byte, hashsize int, conf *skein.Config) []byte { s := New(hashsize, conf) s.Write(msg) return s.Sum(nil) } // New512 returns a hash.Hash computing the Skein1024 512 bit checksum. // The key is optional and turns the hash into a MAC. func New512(key []byte) hash.Hash { s := new(hashFunc) s.initialize(64, &skein.Config{Key: key}) return s } // New256 returns a hash.Hash computing the Skein1024 256 bit checksum. // The key is optional and turns the hash into a MAC. func New256(key []byte) hash.Hash { s := new(hashFunc) s.initialize(32, &skein.Config{Key: key}) return s } // New returns a hash.Hash computing the Skein1024 checksum with the given hash size. // The conf is optional and configurates the hash.Hash func New(hashsize int, conf *skein.Config) hash.Hash { s := new(hashFunc) s.initialize(hashsize, conf) return s } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein1024/skein1024.go000066400000000000000000000103421520706056300261670ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package skein1024 import ( "github.com/enceve/crypto/skein" "github.com/enceve/crypto/skein/threefish" ) type hashFunc struct { hashsize int hVal, hValCpy [17]uint64 tweak [3]uint64 block [threefish.BlockSize1024]byte off int hasMsg bool } func (s *hashFunc) BlockSize() int { return threefish.BlockSize1024 } func (s *hashFunc) Size() int { return s.hashsize } func (s *hashFunc) Reset() { for i := range s.block { s.block[i] = 0 } s.off = 0 s.hasMsg = false s.hVal = s.hValCpy s.tweak[0] = 0 s.tweak[1] = skein.CfgMessage<<56 | skein.FirstBlock } func (s *hashFunc) Write(p []byte) (n int, err error) { s.hasMsg = true n = len(p) var block [16]uint64 dif := threefish.BlockSize1024 - s.off if s.off > 0 && n > dif { s.off += copy(s.block[s.off:], p[:dif]) p = p[dif:] if s.off == threefish.BlockSize1024 && len(p) > 0 { bytesToBlock(&block, s.block[:]) s.update(&block) s.off = 0 } } if length := len(p); length > threefish.BlockSize1024 { nn := length & (^(threefish.BlockSize1024 - 1)) // length -= (length % BlockSize) if length == nn { nn -= threefish.BlockSize1024 } for i := 0; i < len(p[:nn]); i += threefish.BlockSize1024 { bytesToBlock(&block, p[i:]) s.update(&block) } p = p[nn:] } if len(p) > 0 { s.off += copy(s.block[s.off:], p) } return } func (s *hashFunc) Sum(b []byte) []byte { s0 := *s // copy if s0.hasMsg { s0.finalizeHash() } var out [threefish.BlockSize1024]byte var ctr uint64 for i := s0.hashsize; i > 0; i -= threefish.BlockSize1024 { s0.output(&out, ctr) ctr++ b = append(b, out[:]...) } return b[:s0.hashsize] } func (s *hashFunc) update(block *[16]uint64) { threefish.IncrementTweak(&(s.tweak), threefish.BlockSize1024) threefish.UBI1024(block, &(s.hVal), &(s.tweak)) s.tweak[1] &^= skein.FirstBlock } func (s *hashFunc) output(dst *[threefish.BlockSize1024]byte, counter uint64) { var block [16]uint64 block[0] = counter hVal := s.hVal var outTweak = [3]uint64{8, skein.CfgOutput<<56 | skein.FirstBlock | skein.FinalBlock, 0} threefish.UBI1024(&block, &hVal, &outTweak) block[0] ^= counter blockToBytes(dst[:], &block) } func (s *hashFunc) initialize(hashsize int, conf *skein.Config) { if hashsize < 1 { panic("skein1024: invalid hashsize for Skein-1024") } s.hashsize = hashsize var key, pubKey, keyID, nonce, personal []byte if conf != nil { key = conf.Key pubKey = conf.PublicKey keyID = conf.KeyID nonce = conf.Nonce personal = conf.Personal } if len(key) > 0 { s.tweak[0] = 0 s.tweak[1] = skein.CfgKey<<56 | skein.FirstBlock s.Write(key) s.finalizeHash() } var cfg [32]byte schemaId := skein.SchemaID cfg[0] = byte(schemaId) cfg[1] = byte(schemaId >> 8) cfg[2] = byte(schemaId >> 16) cfg[3] = byte(schemaId >> 24) cfg[4] = byte(schemaId >> 32) cfg[5] = byte(schemaId >> 40) cfg[6] = byte(schemaId >> 48) cfg[7] = byte(schemaId >> 56) bits := uint64(s.hashsize * 8) cfg[8] = byte(bits) cfg[9] = byte(bits >> 8) cfg[10] = byte(bits >> 16) cfg[11] = byte(bits >> 24) cfg[12] = byte(bits >> 32) cfg[13] = byte(bits >> 40) cfg[14] = byte(bits >> 48) cfg[15] = byte(bits >> 56) s.tweak[0] = 0 s.tweak[1] = skein.CfgConfig<<56 | skein.FirstBlock s.Write(cfg[:]) s.finalizeHash() if len(personal) > 0 { s.tweak[0] = 0 s.tweak[1] = skein.CfgPersonal<<56 | skein.FirstBlock s.Write(personal) s.finalizeHash() } if len(pubKey) > 0 { s.tweak[0] = 0 s.tweak[1] = skein.CfgPublicKey<<56 | skein.FirstBlock s.Write(pubKey) s.finalizeHash() } if len(keyID) > 0 { s.tweak[0] = 0 s.tweak[1] = skein.CfgKeyID<<56 | skein.FirstBlock s.Write(keyID) s.finalizeHash() } if len(nonce) > 0 { s.tweak[0] = 0 s.tweak[1] = skein.CfgNonce<<56 | skein.FirstBlock s.Write(nonce) s.finalizeHash() } s.hValCpy = s.hVal s.Reset() } func (s *hashFunc) finalizeHash() { threefish.IncrementTweak(&(s.tweak), uint64(s.off)) s.tweak[1] |= skein.FinalBlock // set the last block flag for i := s.off; i < len(s.block); i++ { s.block[i] = 0 } s.off = 0 var block [16]uint64 bytesToBlock(&block, s.block[:]) threefish.UBI1024(&block, &(s.hVal), &(s.tweak)) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein1024/skein1024_amd64.go000066400000000000000000000020741520706056300271650ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // +build amd64 package skein1024 import "unsafe" func bytesToBlock(block *[16]uint64, src []byte) { srcPtr := (*[16]uint64)(unsafe.Pointer(&src[0])) block[0] = srcPtr[0] block[1] = srcPtr[1] block[2] = srcPtr[2] block[3] = srcPtr[3] block[4] = srcPtr[4] block[5] = srcPtr[5] block[6] = srcPtr[6] block[7] = srcPtr[7] block[8] = srcPtr[8] block[9] = srcPtr[9] block[10] = srcPtr[10] block[11] = srcPtr[11] block[12] = srcPtr[12] block[13] = srcPtr[13] block[14] = srcPtr[14] block[15] = srcPtr[15] } func blockToBytes(dst []byte, block *[16]uint64) { dstPtr := (*[16]uint64)(unsafe.Pointer(&dst[0])) dstPtr[0] = block[0] dstPtr[1] = block[1] dstPtr[2] = block[2] dstPtr[3] = block[3] dstPtr[4] = block[4] dstPtr[5] = block[5] dstPtr[6] = block[6] dstPtr[7] = block[7] dstPtr[8] = block[8] dstPtr[9] = block[9] dstPtr[10] = block[10] dstPtr[11] = block[11] dstPtr[12] = block[12] dstPtr[13] = block[13] dstPtr[14] = block[14] dstPtr[15] = block[15] } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein1024/skein1024_ref.go000066400000000000000000000013261520706056300270250ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // +build !amd64 package skein1024 func bytesToBlock(block *[16]uint64, src []byte) { for i := range block { j := i * 8 block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | uint64(src[j+3])<<24 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 } } func blockToBytes(dst []byte, block *[16]uint64) { i := 0 for _, v := range block { dst[i] = byte(v) dst[i+1] = byte(v >> 8) dst[i+2] = byte(v >> 16) dst[i+3] = byte(v >> 24) dst[i+4] = byte(v >> 32) dst[i+5] = byte(v >> 40) dst[i+6] = byte(v >> 48) dst[i+7] = byte(v >> 56) i += 8 } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein1024/vectors_test.go000066400000000000000000000161651520706056300273040ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package skein1024 import ( "bytes" "encoding/hex" "testing" "github.com/enceve/crypto/skein" ) func fromHex(s string) []byte { b, err := hex.DecodeString(s) if err != nil { panic(err) } return b } var testVectors = []struct { hashsize int conf *skein.Config msg, hash string }{ { hashsize: 128, conf: nil, msg: "", hash: "0FFF9563BB3279289227AC77D319B6FFF8D7E9F09DA1247B72A0A265CD6D2A62" + "645AD547ED8193DB48CFF847C06494A03F55666D3B47EB4C20456C9373C86297" + "D630D5578EBD34CB40991578F9F52B18003EFA35D3DA6553FF35DB91B81AB890" + "BEC1B189B7F52CB2A783EBB7D823D725B0B4A71F6824E88F68F982EEFC6D19C6", }, { hashsize: 20, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "2E6A4CBF2EF05EA9C24B93E8D1DE732DDF2739EB", }, { hashsize: 28, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "1D6DE19F37F7A3C265440EECB4B9FBD3300BB5AC60895CFC0D4D3C72", }, { hashsize: 32, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "986A4D472B123E8148731A8EAC9DB23325F0058C4CCBC44A5BB6FE3A8DB672D7", }, { hashsize: 48, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "9C3D0648C11F31C18395D5E6C8EBD73F43D189843FC45235E2C35E345E12D62B" + "C21A41F65896DDC6A04969654C2E2CE9", }, { hashsize: 128, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "96CA81F586C825D0360AEF5ACAEC49AD55289E1797072EEE198B64F349CE65B6" + "E6ED804FE38F05135FE769CC56240DDDA5098F620865CE4A4278C77FA2EC6BC3" + "1C0F354CA78C7CA81665BFCC5DC54258C3B8310ED421D9157F36C093814D9B25" + "103D83E0DDD89C52D0050E13A64C6140E6388431961685734B1F138FE2243086", }, { hashsize: 257, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "56A0CAB1AD315859DA7A6CFC35807CBFE039AF06CA4B8671C053360BDA0B17C1" + "4A9EB5EB2ABB01B0DB3F45C03CD30C69D7C1B70C5C9EF74C06FB3AEF0C843CE9" + "B4C1BA2294DDB5C71CAB692CEDC1E6F908C471B38C0C583418B55AEFDDFE08AB" + "A4055D0D19EDB5CCBA16C3E288471EFE463E6BF6CC346CC74F6C013E0293E6DF" + "D2E4AA66A92242FD395B6D91AAAD5A071C449D77EA00E44ECC75073890AC50D4" + "F4210E8C9DA45385A46D214A0FCCC131DB3F842F955E6E76AC311B3BF439DD51" + "9BEDD691785ADF7540F3163AD1216CF2ADB7D4BF40D93BE3184AEF51B651CA26" + "C7EC44073F43AD689D269EA9FF02F8D2C8932FE6CED0292F97FB5F07CA276D6B" + "43", }, { hashsize: 128, conf: &skein.Config{Key: fromHex("CB41F1706CDE09651203C2D0EFBADDF847A0D315CB2E53FF8BAC41DA0002672E" + "920244C66E02D5F0DAD3E94C42BB65F0D14157DECF4105EF5609D5B0984457C1" + "935DF3061FF06E9F204192BA11E5BB2CAC0430C1C370CB3D113FEA5EC1021EB8" + "75E5946D7A96AC69A1626C6206B7252736F24253C9EE9B85EB852DFC81463134")}, msg: "", hash: "BCF37B3459C88959D6B6B58B2BFE142CEF60C6F4EC56B0702480D7893A2B0595" + "AA354E87102A788B61996B9CBC1EADE7DAFBF6581135572C09666D844C90F066" + "B800FC4F5FD1737644894EF7D588AFC5C38F5D920BDBD3B738AEA3A3267D161E" + "D65284D1F57DA73B68817E17E381CA169115152B869C66B812BB9A84275303F0", }, { hashsize: 128, conf: &skein.Config{Key: fromHex("CB41F1706CDE09651203C2D0EFBADDF847A0D315CB2E53FF8BAC41DA0002672E" + "920244C66E02D5F0DAD3E94C42BB65F0D14157DECF4105EF5609D5B0984457C1" + "935DF3061FF06E9F204192BA11E5BB2CAC0430C1C370CB3D113FEA5EC1021EB8" + "75E5946D7A96AC69A1626C6206B7252736F24253C9EE9B85EB852DFC81463134" + "6C")}, msg: "D3090C72", hash: "DF0596E5808835A3E304AA27923DB05F61DAC57C0696A1D19ABF188E70AA9DBC" + "C659E9510F7C9A37FBC025BD4E5EA293E78ED7838DD0B08864E8AD40DDB3A880" + "31EBEFC21572A89960D1916107A7DA7AC0C067E34EC46A86A29CA63FA250BD39" + "8EB32EC1ED0F8AC8329F26DA018B029E41E2E58D1DFC44DE81615E6C987ED9C9", }, { hashsize: 128, conf: &skein.Config{Key: fromHex("")}, msg: "D3", hash: "F1FBB54F260D0FB9D49A29EEC184B265EDC663668A9720AA61661E43659B3CD6" + "97C700CE1E3E535E0C69801220B5DA975138E7CB1EC8D8E3018F078A32CAE28B" + "C189350B68EE67785623B372EF7811BB06BA6C67E5847596FB72F2B51994EB8E" + "E079B960E228F7026E1BFE8CEA0877496F986FD13DB82E132CC45F70BB010F27", }, } func TestVectors(t *testing.T) { for i, v := range testVectors { conf, msg, ref := v.conf, fromHex(v.msg), fromHex(v.hash) h := New(v.hashsize, conf) h.Write(msg) sum := h.Sum(nil) if !bytes.Equal(sum, ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(ref)) } sum = Sum(msg, v.hashsize, conf) if !bytes.Equal(sum, ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(ref)) } var key []byte if conf != nil { key = conf.Key } switch v.hashsize { case 64: { var out [64]byte Sum512(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } case 48: { var out [48]byte Sum384(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } case 32: { var out [32]byte Sum256(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } case 20: { var out [20]byte Sum160(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein256/000077500000000000000000000000001520706056300241465ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein256/skein.go000066400000000000000000000053031520706056300256070ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // Package skein256 implements the Skein256 hash function // based on the Threefish256 tweakable block cipher. package skein256 import ( "hash" "github.com/enceve/crypto/skein" ) // Sum512 computes the 512 bit Skein256 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum512(out *[64]byte, msg, key []byte) { var out256 [32]byte s := new(hashFunc) s.initialize(64, &skein.Config{Key: key}) s.Write(msg) s.finalizeHash() s.output(&out256, 0) copy(out[:], out256[:]) s.output(&out256, 1) copy(out[32:], out256[:]) } // Sum384 computes the 384 bit Skein256 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum384(out *[48]byte, msg, key []byte) { var out256 [32]byte s := new(hashFunc) s.initialize(48, &skein.Config{Key: key}) s.Write(msg) s.finalizeHash() s.output(&out256, 0) copy(out[:], out256[:]) s.output(&out256, 1) copy(out[32:], out256[:16]) } // Sum256 computes the 256 bit Skein256 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum256(out *[32]byte, msg, key []byte) { s := new(hashFunc) s.initialize(32, &skein.Config{Key: key}) s.Write(msg) s.finalizeHash() s.output(out, 0) } // Sum160 computes the 160 bit Skein256 checksum (or MAC if key is set) of msg // and writes it to out. The key is optional and can be nil. func Sum160(out *[20]byte, msg, key []byte) { var out256 [32]byte s := new(hashFunc) s.initialize(20, &skein.Config{Key: key}) s.Write(msg) s.finalizeHash() s.output(&out256, 0) copy(out[:], out256[:20]) } // Sum returns the Skein256 checksum with the given hash size of msg using the (optional) // conf for configuration. The hashsize must be > 0. func Sum(msg []byte, hashsize int, conf *skein.Config) []byte { s := New(hashsize, conf) s.Write(msg) return s.Sum(nil) } // New512 returns a hash.Hash computing the Skein256 512 bit checksum. // The key is optional and turns the hash into a MAC. func New512(key []byte) hash.Hash { s := new(hashFunc) s.initialize(64, &skein.Config{Key: key}) return s } // New256 returns a hash.Hash computing the Skein256 256 bit checksum. // The key is optional and turns the hash into a MAC. func New256(key []byte) hash.Hash { s := new(hashFunc) s.initialize(32, &skein.Config{Key: key}) return s } // New returns a hash.Hash computing the Skein256 checksum with the given hash size. // The conf is optional and configurates the hash.Hash func New(hashsize int, conf *skein.Config) hash.Hash { s := new(hashFunc) s.initialize(hashsize, conf) return s } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein256/skein256.go000066400000000000000000000103141520706056300260420ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package skein256 import ( "github.com/enceve/crypto/skein" "github.com/enceve/crypto/skein/threefish" ) type hashFunc struct { hashsize int hVal, hValCpy [5]uint64 tweak [3]uint64 block [threefish.BlockSize256]byte off int hasMsg bool } func (s *hashFunc) BlockSize() int { return threefish.BlockSize256 } func (s *hashFunc) Size() int { return s.hashsize } func (s *hashFunc) Reset() { for i := range s.block { s.block[i] = 0 } s.off = 0 s.hasMsg = false s.hVal = s.hValCpy s.tweak[0] = 0 s.tweak[1] = skein.CfgMessage<<56 | skein.FirstBlock } func (s *hashFunc) Write(p []byte) (n int, err error) { s.hasMsg = true n = len(p) var block [4]uint64 dif := threefish.BlockSize256 - s.off if s.off > 0 && n > dif { s.off += copy(s.block[s.off:], p[:dif]) p = p[dif:] if s.off == threefish.BlockSize256 && len(p) > 0 { bytesToBlock(&block, s.block[:]) s.update(&block) s.off = 0 } } if length := len(p); length > threefish.BlockSize256 { nn := length & (^(threefish.BlockSize256 - 1)) // length -= (length % BlockSize) if length == nn { nn -= threefish.BlockSize256 } for i := 0; i < len(p[:nn]); i += threefish.BlockSize256 { bytesToBlock(&block, p[i:]) s.update(&block) } p = p[nn:] } if len(p) > 0 { s.off += copy(s.block[s.off:], p) } return } func (s *hashFunc) Sum(b []byte) []byte { s0 := *s // copy if s0.hasMsg { s0.finalizeHash() } var out [threefish.BlockSize256]byte var ctr uint64 for i := s0.hashsize; i > 0; i -= threefish.BlockSize256 { s0.output(&out, ctr) ctr++ b = append(b, out[:]...) } return b[:s0.hashsize] } func (s *hashFunc) update(block *[4]uint64) { threefish.IncrementTweak(&(s.tweak), threefish.BlockSize256) threefish.UBI256(block, &(s.hVal), &(s.tweak)) s.tweak[1] &^= skein.FirstBlock } func (s *hashFunc) output(dst *[threefish.BlockSize256]byte, counter uint64) { var block [4]uint64 block[0] = counter hVal := s.hVal var outTweak = [3]uint64{8, skein.CfgOutput<<56 | skein.FirstBlock | skein.FinalBlock, 0} threefish.UBI256(&block, &hVal, &outTweak) block[0] ^= counter blockToBytes(dst[:], &block) } func (s *hashFunc) initialize(hashsize int, conf *skein.Config) { if hashsize < 1 { panic("skein256: invalid hashsize for Skein-256") } s.hashsize = hashsize var key, pubKey, keyID, nonce, personal []byte if conf != nil { key = conf.Key pubKey = conf.PublicKey keyID = conf.KeyID nonce = conf.Nonce personal = conf.Personal } if len(key) > 0 { s.tweak[0] = 0 s.tweak[1] = skein.CfgKey<<56 | skein.FirstBlock s.Write(key) s.finalizeHash() } var cfg [32]byte schemaId := skein.SchemaID cfg[0] = byte(schemaId) cfg[1] = byte(schemaId >> 8) cfg[2] = byte(schemaId >> 16) cfg[3] = byte(schemaId >> 24) cfg[4] = byte(schemaId >> 32) cfg[5] = byte(schemaId >> 40) cfg[6] = byte(schemaId >> 48) cfg[7] = byte(schemaId >> 56) bits := uint64(s.hashsize * 8) cfg[8] = byte(bits) cfg[9] = byte(bits >> 8) cfg[10] = byte(bits >> 16) cfg[11] = byte(bits >> 24) cfg[12] = byte(bits >> 32) cfg[13] = byte(bits >> 40) cfg[14] = byte(bits >> 48) cfg[15] = byte(bits >> 56) s.tweak[0] = 0 s.tweak[1] = skein.CfgConfig<<56 | skein.FirstBlock s.Write(cfg[:]) s.finalizeHash() if len(personal) > 0 { s.tweak[0] = 0 s.tweak[1] = skein.CfgPersonal<<56 | skein.FirstBlock s.Write(personal) s.finalizeHash() } if len(pubKey) > 0 { s.tweak[0] = 0 s.tweak[1] = skein.CfgPublicKey<<56 | skein.FirstBlock s.Write(pubKey) s.finalizeHash() } if len(keyID) > 0 { s.tweak[0] = 0 s.tweak[1] = skein.CfgKeyID<<56 | skein.FirstBlock s.Write(keyID) s.finalizeHash() } if len(nonce) > 0 { s.tweak[0] = 0 s.tweak[1] = skein.CfgNonce<<56 | skein.FirstBlock s.Write(nonce) s.finalizeHash() } s.hValCpy = s.hVal s.Reset() } func (s *hashFunc) finalizeHash() { threefish.IncrementTweak(&(s.tweak), uint64(s.off)) s.tweak[1] |= skein.FinalBlock // set the last block flag for i := s.off; i < len(s.block); i++ { s.block[i] = 0 } s.off = 0 var block [4]uint64 bytesToBlock(&block, s.block[:]) threefish.UBI256(&block, &(s.hVal), &(s.tweak)) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein256/skein256_amd64.go000066400000000000000000000010171520706056300270350ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // +build amd64 package skein256 import "unsafe" func bytesToBlock(block *[4]uint64, src []byte) { srcPtr := (*[4]uint64)(unsafe.Pointer(&src[0])) block[0] = srcPtr[0] block[1] = srcPtr[1] block[2] = srcPtr[2] block[3] = srcPtr[3] } func blockToBytes(dst []byte, block *[4]uint64) { dstPtr := (*[4]uint64)(unsafe.Pointer(&dst[0])) dstPtr[0] = block[0] dstPtr[1] = block[1] dstPtr[2] = block[2] dstPtr[3] = block[3] } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein256/skein256_ref.go000066400000000000000000000013231520706056300266760ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // +build !amd64 package skein256 func bytesToBlock(block *[4]uint64, src []byte) { for i := range block { j := i * 8 block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | uint64(src[j+3])<<24 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 } } func blockToBytes(dst []byte, block *[4]uint64) { i := 0 for _, v := range block { dst[i] = byte(v) dst[i+1] = byte(v >> 8) dst[i+2] = byte(v >> 16) dst[i+3] = byte(v >> 24) dst[i+4] = byte(v >> 32) dst[i+5] = byte(v >> 40) dst[i+6] = byte(v >> 48) dst[i+7] = byte(v >> 56) i += 8 } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein256/vectors_test.go000066400000000000000000000133451520706056300272270ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package skein256 import ( "bytes" "encoding/hex" "testing" "github.com/enceve/crypto/skein" ) func fromHex(s string) []byte { b, err := hex.DecodeString(s) if err != nil { panic(err) } return b } var testVectors = []struct { hashsize int conf *skein.Config msg, hash string }{ { hashsize: 32, conf: nil, msg: "", hash: "C8877087DA56E072870DAA843F176E9453115929094C3A40C463A196C29BF7BA", }, { hashsize: 32, conf: nil, msg: "FF", hash: "0B98DCD198EA0E50A7A244C444E25C23DA30C10FC9A1F270A6637F1F34E67ED2", }, { hashsize: 32, conf: nil, msg: "FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0", hash: "8D0FA4EF777FD759DFD4044E6F6A5AC3C774AEC943DCFC07927B723B5DBF408B", }, { hashsize: 32, conf: nil, msg: "FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0" + "DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0", hash: "DF28E916630D0B44C4A849DC9A02F07A07CB30F732318256B15D865AC4AE162F", }, { hashsize: 20, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "0CD491B7715704C3A15A45A1CA8D93F8F646D3A1", }, { hashsize: 28, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "AFD1E2D0F5B6CD4E1F8B3935FA2497D27EE97E72060ADAC099543487", }, { hashsize: 32, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "4DE6FE2BFDAA3717A4261030EF0E044CED9225D066354610842A24A3EAFD1DCF", }, { hashsize: 48, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "954620FB31E8B782A2794C6542827026FE069D715DF04261629FCBE81D7D529B" + "95BA021FA4239FB00AFAA75F5FD8E78B", }, { hashsize: 64, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "51347E27C7EABBA514959F899A6715EF6AD5CF01C23170590E6A8AF399470BF9" + "0EA7409960A708C1DBAA90E86389DF254ABC763639BB8CDF7FB663B29D9557C3", }, { hashsize: 32, conf: &skein.Config{Key: fromHex("CB41F1706CDE09651203C2D0EFBADDF8")}, msg: "", hash: "886E4EFEFC15F06AA298963971D7A25398FFFE5681C84DB39BD00851F64AE29D", }, { hashsize: 32, conf: &skein.Config{Key: fromHex("")}, msg: "D3090C72167517F7C7AD82A70C2FD3F6443F608301591E59", hash: "DCBD5C8BD09021A840B0EA4AAA2F06E67D7EEBE882B49DE6B74BDC56B60CC48F", }, { hashsize: 48, conf: &skein.Config{Key: fromHex("CB41F1706CDE09651203C2D0EFBADDF847A0D315CB2E53FF8BAC41DA0002672E92")}, msg: "D3090C72167517F7C7AD82A70C2FD3F6443F608301591E598EADB195E8357135" + "BA26FEDE2EE187417F816048D00FC23512737A2113709A77E4170C49A94B7FDF" + "F45FF579A72287743102E7766C35CA5ABC5DFE2F63A1E726CE5FBD2926DB03A2" + "DD18B03FC1508A9AAC45EB362440203A323E09EDEE6324EE2E37B4432C1867ED", hash: "96E6CEBB23573D0A70CE36A67AA05D2403148093F25C695E1254887CC97F9771" + "D2518413AF4286BF2A06B61A53F7FCEC", }, } func TestVectors(t *testing.T) { for i, v := range testVectors { conf, msg, ref := v.conf, fromHex(v.msg), fromHex(v.hash) h := New(v.hashsize, conf) h.Write(msg) sum := h.Sum(nil) if !bytes.Equal(sum, ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(ref)) } sum = Sum(msg, v.hashsize, conf) if !bytes.Equal(sum, ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(ref)) } var key []byte if conf != nil { key = conf.Key } switch v.hashsize { case 64: { var out [64]byte Sum512(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } case 48: { var out [48]byte Sum384(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } case 32: { var out [32]byte Sum256(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } case 20: { var out [20]byte Sum160(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein512.go000066400000000000000000000075551520706056300245040ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package skein import ( "github.com/enceve/crypto/skein/threefish" ) type hashFunc struct { hashsize int hVal, hValCpy [9]uint64 tweak [3]uint64 block [BlockSize]byte off int hasMsg bool } func (s *hashFunc) BlockSize() int { return BlockSize } func (s *hashFunc) Size() int { return s.hashsize } func (s *hashFunc) Reset() { for i := range s.block { s.block[i] = 0 } s.off = 0 s.hasMsg = false s.hVal = s.hValCpy s.tweak[0] = 0 s.tweak[1] = CfgMessage<<56 | FirstBlock } func (s *hashFunc) Write(p []byte) (n int, err error) { s.hasMsg = true n = len(p) var block [8]uint64 dif := BlockSize - s.off if s.off > 0 && n > dif { s.off += copy(s.block[s.off:], p[:dif]) p = p[dif:] if s.off == BlockSize && len(p) > 0 { bytesToBlock(&block, s.block[:]) s.update(&block) s.off = 0 } } if length := len(p); length > BlockSize { nn := length & (^(BlockSize - 1)) // length -= (length % BlockSize) if length == nn { nn -= BlockSize } for i := 0; i < len(p[:nn]); i += BlockSize { bytesToBlock(&block, p[i:]) s.update(&block) } p = p[nn:] } if len(p) > 0 { s.off += copy(s.block[s.off:], p) } return } func (s *hashFunc) Sum(b []byte) []byte { s0 := *s // copy if s0.hasMsg { s0.finalizeHash() } var out [BlockSize]byte var ctr uint64 for i := s0.hashsize; i > 0; i -= BlockSize { s0.output(&out, ctr) ctr++ b = append(b, out[:]...) } return b[:s0.hashsize] } func (s *hashFunc) update(block *[8]uint64) { threefish.IncrementTweak(&(s.tweak), BlockSize) threefish.UBI512(block, &(s.hVal), &(s.tweak)) s.tweak[1] &^= FirstBlock } func (s *hashFunc) output(dst *[BlockSize]byte, counter uint64) { var block [8]uint64 block[0] = counter hVal := s.hVal var outTweak = [3]uint64{8, CfgOutput<<56 | FirstBlock | FinalBlock, 0} threefish.UBI512(&block, &hVal, &outTweak) block[0] ^= counter blockToBytes(dst[:], &block) } func (s *hashFunc) initialize(hashsize int, conf *Config) { if hashsize < 1 { panic("skein: invalid hashsize for Skein-512") } s.hashsize = hashsize var key, pubKey, keyID, nonce, personal []byte if conf != nil { key = conf.Key pubKey = conf.PublicKey keyID = conf.KeyID nonce = conf.Nonce personal = conf.Personal } if len(key) > 0 { s.tweak[0] = 0 s.tweak[1] = CfgKey<<56 | FirstBlock s.Write(key) s.finalizeHash() } var cfg [32]byte schemaId := SchemaID cfg[0] = byte(schemaId) cfg[1] = byte(schemaId >> 8) cfg[2] = byte(schemaId >> 16) cfg[3] = byte(schemaId >> 24) cfg[4] = byte(schemaId >> 32) cfg[5] = byte(schemaId >> 40) cfg[6] = byte(schemaId >> 48) cfg[7] = byte(schemaId >> 56) bits := uint64(s.hashsize * 8) cfg[8] = byte(bits) cfg[9] = byte(bits >> 8) cfg[10] = byte(bits >> 16) cfg[11] = byte(bits >> 24) cfg[12] = byte(bits >> 32) cfg[13] = byte(bits >> 40) cfg[14] = byte(bits >> 48) cfg[15] = byte(bits >> 56) s.tweak[0] = 0 s.tweak[1] = CfgConfig<<56 | FirstBlock s.Write(cfg[:]) s.finalizeHash() if len(personal) > 0 { s.tweak[0] = 0 s.tweak[1] = CfgPersonal<<56 | FirstBlock s.Write(personal) s.finalizeHash() } if len(pubKey) > 0 { s.tweak[0] = 0 s.tweak[1] = CfgPublicKey<<56 | FirstBlock s.Write(pubKey) s.finalizeHash() } if len(keyID) > 0 { s.tweak[0] = 0 s.tweak[1] = CfgKeyID<<56 | FirstBlock s.Write(keyID) s.finalizeHash() } if len(nonce) > 0 { s.tweak[0] = 0 s.tweak[1] = CfgNonce<<56 | FirstBlock s.Write(nonce) s.finalizeHash() } s.hValCpy = s.hVal s.Reset() } func (s *hashFunc) finalizeHash() { threefish.IncrementTweak(&(s.tweak), uint64(s.off)) s.tweak[1] |= FinalBlock for i := s.off; i < len(s.block); i++ { s.block[i] = 0 } s.off = 0 var block [8]uint64 bytesToBlock(&block, s.block[:]) threefish.UBI512(&block, &(s.hVal), &(s.tweak)) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein512_amd64.go000066400000000000000000000012741520706056300254670ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // +build amd64 package skein import "unsafe" func bytesToBlock(block *[8]uint64, src []byte) { srcPtr := (*[8]uint64)(unsafe.Pointer(&src[0])) block[0] = srcPtr[0] block[1] = srcPtr[1] block[2] = srcPtr[2] block[3] = srcPtr[3] block[4] = srcPtr[4] block[5] = srcPtr[5] block[6] = srcPtr[6] block[7] = srcPtr[7] } func blockToBytes(dst []byte, block *[8]uint64) { dstPtr := (*[8]uint64)(unsafe.Pointer(&dst[0])) dstPtr[0] = block[0] dstPtr[1] = block[1] dstPtr[2] = block[2] dstPtr[3] = block[3] dstPtr[4] = block[4] dstPtr[5] = block[5] dstPtr[6] = block[6] dstPtr[7] = block[7] } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein512_ref.go000066400000000000000000000013201520706056300253200ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // +build !amd64 package skein func bytesToBlock(block *[8]uint64, src []byte) { for i := range block { j := i * 8 block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | uint64(src[j+3])<<24 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 } } func blockToBytes(dst []byte, block *[8]uint64) { i := 0 for _, v := range block { dst[i] = byte(v) dst[i+1] = byte(v >> 8) dst[i+2] = byte(v >> 16) dst[i+3] = byte(v >> 24) dst[i+4] = byte(v >> 32) dst[i+5] = byte(v >> 40) dst[i+6] = byte(v >> 48) dst[i+7] = byte(v >> 56) i += 8 } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/skein_test.go000066400000000000000000000102251520706056300252770ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package skein import ( "bytes" "encoding/hex" "hash" "testing" ) func testWrite(msg string, t *testing.T, h hash.Hash, c *Config) { var msg1 []byte msg0 := make([]byte, 64) for i := range msg0 { h.Write(msg0[:i]) msg1 = append(msg1, msg0[:i]...) } tag0 := h.Sum(nil) tag1 := Sum(msg1, h.Size(), c) if !bytes.Equal(tag0, tag1) { t.Fatalf("%s\nSum differ from Sum\n Sum: %s \n skein.Sum: %s", msg, hex.EncodeToString(tag0), hex.EncodeToString(tag1)) } } func TestWrite(t *testing.T) { testWrite("testWrite(t, New256(nil), nil)", t, New256(nil), nil) testWrite("testWrite(t, New256(make([]byte, 16)), &Config{Key: make([]byte, 16)})", t, New256(make([]byte, 16)), &Config{Key: make([]byte, 16)}) testWrite("testWrite(t, New512(nil), nil)", t, New512(nil), nil) testWrite("testWrite(t, New512(make([]byte, 16)), &Config{Key: make([]byte, 16)})", t, New512(make([]byte, 16)), &Config{Key: make([]byte, 16)}) testWrite("testWrite(t, New(128, nil), nil)", t, New(128, nil), nil) testWrite("testWrite(t, New(128, &Config{Key: make([]byte, 16)}), &Config{Key: make([]byte, 16)})", t, New(128, &Config{Key: make([]byte, 16)}), &Config{Key: make([]byte, 16)}) } func TestBlockSize(t *testing.T) { h := New(64, nil) if bs := h.BlockSize(); bs != BlockSize { t.Fatalf("BlockSize() returned: %d - but expected: %d", bs, BlockSize) } } func TestSum(t *testing.T) { sizes := []int{20, 32, 48, 64} key := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} msg := make([]byte, 512) for i := range msg { msg[i] = byte(i) + key[i%len(key)] } c := &Config{Key: key} for _, hashsize := range sizes { switch hashsize { case 20: { var sum0 [20]byte Sum160(&sum0, msg, key) sum1 := Sum(msg, hashsize, c) if !bytes.Equal(sum0[:], sum1) { t.Fatalf("Sum160 differ from Sum: Sum160: %s\n Sum: %s", hex.EncodeToString(sum0[:]), hex.EncodeToString(sum1)) } } case 32: { var sum0 [32]byte Sum256(&sum0, msg, key) sum1 := Sum(msg, hashsize, c) if !bytes.Equal(sum0[:], sum1) { t.Fatalf("Sum256 differ from Sum: Sum256: %s\n Sum: %s", hex.EncodeToString(sum0[:]), hex.EncodeToString(sum1)) } } case 48: { var sum0 [48]byte Sum384(&sum0, msg, key) sum1 := Sum(msg, hashsize, c) if !bytes.Equal(sum0[:], sum1) { t.Fatalf("Sum384 differ from Sum: Sum384: %s\n Sum: %s", hex.EncodeToString(sum0[:]), hex.EncodeToString(sum1)) } } case 64: { var sum0 [64]byte Sum512(&sum0, msg, key) sum1 := Sum(msg, hashsize, c) if !bytes.Equal(sum0[:], sum1) { t.Fatalf("Sum512 differ from Sum: Sum512: %s\n Sum: %s", hex.EncodeToString(sum0[:]), hex.EncodeToString(sum1)) } } } } } func TestInitialize(t *testing.T) { rec := func() { if err := recover(); err == nil { t.Fatal("Recover expected error, but no one occured") } } mustFail := func() { defer rec() s := new(hashFunc) s.initialize(0, nil) } mustFail() c := &Config{ Key: make([]byte, 16), KeyID: make([]byte, 16), Personal: make([]byte, 8), Nonce: make([]byte, 12), PublicKey: make([]byte, 128), } testWrite("testWrite(t, New(64, c), c)", t, New(64, c), c) } // Benchmarks func benchmarkSum(b *testing.B, size int) { msg := make([]byte, size) b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { Sum(msg, 64, nil) } } func benchmarkSum512(b *testing.B, size int) { var sum [64]byte msg := make([]byte, size) b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { Sum512(&sum, msg, nil) } } func BenchmarkSum_64(b *testing.B) { benchmarkSum(b, 64) } func BenchmarkSum_1K(b *testing.B) { benchmarkSum(b, 1024) } func BenchmarkSum512_64(b *testing.B) { benchmarkSum512(b, 64) } func BenchmarkSum512_1K(b *testing.B) { benchmarkSum512(b, 1024) } func benchmarkWrite(b *testing.B, size int) { h := New512(nil) msg := make([]byte, size) b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { h.Write(msg) } } func BenchmarkWrite_64(b *testing.B) { benchmarkWrite(b, 64) } func BenchmarkWrite_1K(b *testing.B) { benchmarkWrite(b, 1024) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/threefish/000077500000000000000000000000001520706056300245615ustar00rootroot00000000000000golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/threefish/threefish.go000066400000000000000000000043461520706056300271000ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // Package threefish implements the Threefish tweakable block cipher. // Threefish is designed to be the core function of the Skein hash function // family. // There are three versions of Threefish // - Threefish256 processes 256 bit blocks // - Threefish512 processes 512 bit blocks // - Threefish1024 processes 1024 bit blocks package threefish import ( "crypto/cipher" "github.com/enceve/crypto" ) const ( // The size of the tweak in bytes. TweakSize = 16 // C240 is the key schedule constant C240 = 0x1bd11bdaa9fc1a22 // The block size of Threefish-256 in bytes. BlockSize256 = 32 // The block size of Threefish-512 in bytes. BlockSize512 = 64 // The block size of Threefish-1024 in bytes. BlockSize1024 = 128 ) // NewCipher returns a cipher.Block implementing the Threefish cipher. // The length of the key must be 32, 64 or 128 byte. // The length of the tweak must be TweakSize. // The returned cipher implements: // - Threefish-256 - if len(key) = 32 // - Threefish-512 - if len(key) = 64 // - Threefish-1024 - if len(key) = 128 func NewCipher(tweak *[TweakSize]byte, key []byte) (cipher.Block, error) { switch k := len(key); k { default: return nil, crypto.KeySizeError(k) case BlockSize256: return newCipher256(tweak, key), nil case BlockSize512: return newCipher512(tweak, key), nil case BlockSize1024: return newCipher1024(tweak, key), nil } } // Increment the tweak by the ctr argument. // Skein can consume messages up to 2^96 -1 bytes. func IncrementTweak(tweak *[3]uint64, ctr uint64) { t0 := tweak[0] tweak[0] += ctr if tweak[0] < t0 { t1 := tweak[1] tweak[1] = (t1 + 1) & 0x00000000FFFFFFFF } } // The threefish-256 tweakable blockcipher type threefish256 struct { keys [5]uint64 tweak [3]uint64 } func (t *threefish256) BlockSize() int { return BlockSize256 } // The threefish-512 tweakable blockcipher type threefish512 struct { keys [9]uint64 tweak [3]uint64 } func (t *threefish512) BlockSize() int { return BlockSize512 } // The threefish-1024 tweakable blockcipher type threefish1024 struct { keys [17]uint64 tweak [3]uint64 } func (t *threefish1024) BlockSize() int { return BlockSize1024 } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/threefish/threefish1024_ref.go000066400000000000000000000345071520706056300302450ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package threefish func (t *threefish1024) Encrypt(dst, src []byte) { var block [16]uint64 bytesToBlock1024(&block, src) Encrypt1024(&block, &(t.keys), &(t.tweak)) block1024ToBytes(dst, &block) } func (t *threefish1024) Decrypt(dst, src []byte) { var block [16]uint64 bytesToBlock1024(&block, src) Decrypt1024(&block, &(t.keys), &(t.tweak)) block1024ToBytes(dst, &block) } func newCipher1024(tweak *[TweakSize]byte, key []byte) *threefish1024 { c := new(threefish1024) c.tweak[0] = uint64(tweak[0]) | uint64(tweak[1])<<8 | uint64(tweak[2])<<16 | uint64(tweak[3])<<24 | uint64(tweak[4])<<32 | uint64(tweak[5])<<40 | uint64(tweak[6])<<48 | uint64(tweak[7])<<56 c.tweak[1] = uint64(tweak[8]) | uint64(tweak[9])<<8 | uint64(tweak[10])<<16 | uint64(tweak[11])<<24 | uint64(tweak[12])<<32 | uint64(tweak[13])<<40 | uint64(tweak[14])<<48 | uint64(tweak[15])<<56 c.tweak[2] = c.tweak[0] ^ c.tweak[1] for i := range c.keys[:16] { j := i * 8 c.keys[i] = uint64(key[j]) | uint64(key[j+1])<<8 | uint64(key[j+2])<<16 | uint64(key[j+3])<<24 | uint64(key[j+4])<<32 | uint64(key[j+5])<<40 | uint64(key[j+6])<<48 | uint64(key[j+7])<<56 } c.keys[16] = C240 ^ c.keys[0] ^ c.keys[1] ^ c.keys[2] ^ c.keys[3] ^ c.keys[4] ^ c.keys[5] ^ c.keys[6] ^ c.keys[7] ^ c.keys[8] ^ c.keys[9] ^ c.keys[10] ^ c.keys[11] ^ c.keys[12] ^ c.keys[13] ^ c.keys[14] ^ c.keys[15] return c } // Encrypt1024 encrypts the 16 words of block using the expanded 1024 bit key and // the 128 bit tweak. The keys[16] must be keys[0] xor keys[1] xor ... keys[15] xor C240. // The tweak[2] must be tweak[0] xor tweak[1]. func Encrypt1024(block *[16]uint64, keys *[17]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3] b4, b5, b6, b7 := block[4], block[5], block[6], block[7] b8, b9, b10, b11 := block[8], block[9], block[10], block[11] b12, b13, b14, b15 := block[12], block[13], block[14], block[15] for r := 0; r < 19; r++ { b0 += keys[r%17] b1 += keys[(r+1)%17] b2 += keys[(r+2)%17] b3 += keys[(r+3)%17] b4 += keys[(r+4)%17] b5 += keys[(r+5)%17] b6 += keys[(r+6)%17] b7 += keys[(r+7)%17] b8 += keys[(r+8)%17] b9 += keys[(r+9)%17] b10 += keys[(r+10)%17] b11 += keys[(r+11)%17] b12 += keys[(r+12)%17] b13 += keys[(r+13)%17] + tweak[r%3] b14 += keys[(r+14)%17] + tweak[(r+1)%3] b15 += keys[(r+15)%17] + uint64(r) b0 += b1 b1 = ((b1 << 24) | (b1 >> (64 - 24))) ^ b0 b2 += b3 b3 = ((b3 << 13) | (b3 >> (64 - 13))) ^ b2 b4 += b5 b5 = ((b5 << 8) | (b5 >> (64 - 8))) ^ b4 b6 += b7 b7 = ((b7 << 47) | (b7 >> (64 - 47))) ^ b6 b8 += b9 b9 = ((b9 << 8) | (b9 >> (64 - 8))) ^ b8 b10 += b11 b11 = ((b11 << 17) | (b11 >> (64 - 17))) ^ b10 b12 += b13 b13 = ((b13 << 22) | (b13 >> (64 - 22))) ^ b12 b14 += b15 b15 = ((b15 << 37) | (b15 >> (64 - 37))) ^ b14 b0 += b9 b9 = ((b9 << 38) | (b9 >> (64 - 38))) ^ b0 b2 += b13 b13 = ((b13 << 19) | (b13 >> (64 - 19))) ^ b2 b6 += b11 b11 = ((b11 << 10) | (b11 >> (64 - 10))) ^ b6 b4 += b15 b15 = ((b15 << 55) | (b15 >> (64 - 55))) ^ b4 b10 += b7 b7 = ((b7 << 49) | (b7 >> (64 - 49))) ^ b10 b12 += b3 b3 = ((b3 << 18) | (b3 >> (64 - 18))) ^ b12 b14 += b5 b5 = ((b5 << 23) | (b5 >> (64 - 23))) ^ b14 b8 += b1 b1 = ((b1 << 52) | (b1 >> (64 - 52))) ^ b8 b0 += b7 b7 = ((b7 << 33) | (b7 >> (64 - 33))) ^ b0 b2 += b5 b5 = ((b5 << 4) | (b5 >> (64 - 4))) ^ b2 b4 += b3 b3 = ((b3 << 51) | (b3 >> (64 - 51))) ^ b4 b6 += b1 b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b6 b12 += b15 b15 = ((b15 << 34) | (b15 >> (64 - 34))) ^ b12 b14 += b13 b13 = ((b13 << 41) | (b13 >> (64 - 41))) ^ b14 b8 += b11 b11 = ((b11 << 59) | (b11 >> (64 - 59))) ^ b8 b10 += b9 b9 = ((b9 << 17) | (b9 >> (64 - 17))) ^ b10 b0 += b15 b15 = ((b15 << 5) | (b15 >> (64 - 5))) ^ b0 b2 += b11 b11 = ((b11 << 20) | (b11 >> (64 - 20))) ^ b2 b6 += b13 b13 = ((b13 << 48) | (b13 >> (64 - 48))) ^ b6 b4 += b9 b9 = ((b9 << 41) | (b9 >> (64 - 41))) ^ b4 b14 += b1 b1 = ((b1 << 47) | (b1 >> (64 - 47))) ^ b14 b8 += b5 b5 = ((b5 << 28) | (b5 >> (64 - 28))) ^ b8 b10 += b3 b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b10 b12 += b7 b7 = ((b7 << 25) | (b7 >> (64 - 25))) ^ b12 r++ b0 += keys[r%17] b1 += keys[(r+1)%17] b2 += keys[(r+2)%17] b3 += keys[(r+3)%17] b4 += keys[(r+4)%17] b5 += keys[(r+5)%17] b6 += keys[(r+6)%17] b7 += keys[(r+7)%17] b8 += keys[(r+8)%17] b9 += keys[(r+9)%17] b10 += keys[(r+10)%17] b11 += keys[(r+11)%17] b12 += keys[(r+12)%17] b13 += keys[(r+13)%17] + tweak[r%3] b14 += keys[(r+14)%17] + tweak[(r+1)%3] b15 += keys[(r+15)%17] + uint64(r) b0 += b1 b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b0 b2 += b3 b3 = ((b3 << 9) | (b3 >> (64 - 9))) ^ b2 b4 += b5 b5 = ((b5 << 37) | (b5 >> (64 - 37))) ^ b4 b6 += b7 b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b6 b8 += b9 b9 = ((b9 << 12) | (b9 >> (64 - 12))) ^ b8 b10 += b11 b11 = ((b11 << 47) | (b11 >> (64 - 47))) ^ b10 b12 += b13 b13 = ((b13 << 44) | (b13 >> (64 - 44))) ^ b12 b14 += b15 b15 = ((b15 << 30) | (b15 >> (64 - 30))) ^ b14 b0 += b9 b9 = ((b9 << 16) | (b9 >> (64 - 16))) ^ b0 b2 += b13 b13 = ((b13 << 34) | (b13 >> (64 - 34))) ^ b2 b6 += b11 b11 = ((b11 << 56) | (b11 >> (64 - 56))) ^ b6 b4 += b15 b15 = ((b15 << 51) | (b15 >> (64 - 51))) ^ b4 b10 += b7 b7 = ((b7 << 4) | (b7 >> (64 - 4))) ^ b10 b12 += b3 b3 = ((b3 << 53) | (b3 >> (64 - 53))) ^ b12 b14 += b5 b5 = ((b5 << 42) | (b5 >> (64 - 42))) ^ b14 b8 += b1 b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b8 b0 += b7 b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b0 b2 += b5 b5 = ((b5 << 44) | (b5 >> (64 - 44))) ^ b2 b4 += b3 b3 = ((b3 << 47) | (b3 >> (64 - 47))) ^ b4 b6 += b1 b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b6 b12 += b15 b15 = ((b15 << 19) | (b15 >> (64 - 19))) ^ b12 b14 += b13 b13 = ((b13 << 42) | (b13 >> (64 - 42))) ^ b14 b8 += b11 b11 = ((b11 << 44) | (b11 >> (64 - 44))) ^ b8 b10 += b9 b9 = ((b9 << 25) | (b9 >> (64 - 25))) ^ b10 b0 += b15 b15 = ((b15 << 9) | (b15 >> (64 - 9))) ^ b0 b2 += b11 b11 = ((b11 << 48) | (b11 >> (64 - 48))) ^ b2 b6 += b13 b13 = ((b13 << 35) | (b13 >> (64 - 35))) ^ b6 b4 += b9 b9 = ((b9 << 52) | (b9 >> (64 - 52))) ^ b4 b14 += b1 b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b14 b8 += b5 b5 = ((b5 << 31) | (b5 >> (64 - 31))) ^ b8 b10 += b3 b3 = ((b3 << 37) | (b3 >> (64 - 37))) ^ b10 b12 += b7 b7 = ((b7 << 20) | (b7 >> (64 - 20))) ^ b12 } b0 += keys[3] b1 += keys[4] b2 += keys[5] b3 += keys[6] b4 += keys[7] b5 += keys[8] b6 += keys[9] b7 += keys[10] b8 += keys[11] b9 += keys[12] b10 += keys[13] b11 += keys[14] b12 += keys[15] b13 += keys[16] + tweak[2] b14 += keys[0] + tweak[0] b15 += keys[1] + 20 block[0], block[1], block[2], block[3] = b0, b1, b2, b3 block[4], block[5], block[6], block[7] = b4, b5, b6, b7 block[8], block[9], block[10], block[11] = b8, b9, b10, b11 block[12], block[13], block[14], block[15] = b12, b13, b14, b15 } // Decrypt1024 decrypts the 16 words of block using the expanded 1024 bit key and // the 128 bit tweak. The keys[16] must be keys[0] xor keys[1] xor ... keys[15] xor C240. // The tweak[2] must be tweak[0] xor tweak[1]. func Decrypt1024(block *[16]uint64, keys *[17]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3] b4, b5, b6, b7 := block[4], block[5], block[6], block[7] b8, b9, b10, b11 := block[8], block[9], block[10], block[11] b12, b13, b14, b15 := block[12], block[13], block[14], block[15] var tmp uint64 for r := 20; r > 1; r-- { b0 -= keys[r%17] b1 -= keys[(r+1)%17] b2 -= keys[(r+2)%17] b3 -= keys[(r+3)%17] b4 -= keys[(r+4)%17] b5 -= keys[(r+5)%17] b6 -= keys[(r+6)%17] b7 -= keys[(r+7)%17] b8 -= keys[(r+8)%17] b9 -= keys[(r+9)%17] b10 -= keys[(r+10)%17] b11 -= keys[(r+11)%17] b12 -= keys[(r+12)%17] b13 -= keys[(r+13)%17] + tweak[r%3] b14 -= keys[(r+14)%17] + tweak[(r+1)%3] b15 -= keys[(r+15)%17] + uint64(r) tmp = b7 ^ b12 b7 = (tmp >> 20) | (tmp << (64 - 20)) b12 -= b7 tmp = b3 ^ b10 b3 = (tmp >> 37) | (tmp << (64 - 37)) b10 -= b3 tmp = b5 ^ b8 b5 = (tmp >> 31) | (tmp << (64 - 31)) b8 -= b5 tmp = b1 ^ b14 b1 = (tmp >> 23) | (tmp << (64 - 23)) b14 -= b1 tmp = b9 ^ b4 b9 = (tmp >> 52) | (tmp << (64 - 52)) b4 -= b9 tmp = b13 ^ b6 b13 = (tmp >> 35) | (tmp << (64 - 35)) b6 -= b13 tmp = b11 ^ b2 b11 = (tmp >> 48) | (tmp << (64 - 48)) b2 -= b11 tmp = b15 ^ b0 b15 = (tmp >> 9) | (tmp << (64 - 9)) b0 -= b15 tmp = b9 ^ b10 b9 = (tmp >> 25) | (tmp << (64 - 25)) b10 -= b9 tmp = b11 ^ b8 b11 = (tmp >> 44) | (tmp << (64 - 44)) b8 -= b11 tmp = b13 ^ b14 b13 = (tmp >> 42) | (tmp << (64 - 42)) b14 -= b13 tmp = b15 ^ b12 b15 = (tmp >> 19) | (tmp << (64 - 19)) b12 -= b15 tmp = b1 ^ b6 b1 = (tmp >> 46) | (tmp << (64 - 46)) b6 -= b1 tmp = b3 ^ b4 b3 = (tmp >> 47) | (tmp << (64 - 47)) b4 -= b3 tmp = b5 ^ b2 b5 = (tmp >> 44) | (tmp << (64 - 44)) b2 -= b5 tmp = b7 ^ b0 b7 = (tmp >> 31) | (tmp << (64 - 31)) b0 -= b7 tmp = b1 ^ b8 b1 = (tmp >> 41) | (tmp << (64 - 41)) b8 -= b1 tmp = b5 ^ b14 b5 = (tmp >> 42) | (tmp << (64 - 42)) b14 -= b5 tmp = b3 ^ b12 b3 = (tmp >> 53) | (tmp << (64 - 53)) b12 -= b3 tmp = b7 ^ b10 b7 = (tmp >> 4) | (tmp << (64 - 4)) b10 -= b7 tmp = b15 ^ b4 b15 = (tmp >> 51) | (tmp << (64 - 51)) b4 -= b15 tmp = b11 ^ b6 b11 = (tmp >> 56) | (tmp << (64 - 56)) b6 -= b11 tmp = b13 ^ b2 b13 = (tmp >> 34) | (tmp << (64 - 34)) b2 -= b13 tmp = b9 ^ b0 b9 = (tmp >> 16) | (tmp << (64 - 16)) b0 -= b9 tmp = b15 ^ b14 b15 = (tmp >> 30) | (tmp << (64 - 30)) b14 -= b15 tmp = b13 ^ b12 b13 = (tmp >> 44) | (tmp << (64 - 44)) b12 -= b13 tmp = b11 ^ b10 b11 = (tmp >> 47) | (tmp << (64 - 47)) b10 -= b11 tmp = b9 ^ b8 b9 = (tmp >> 12) | (tmp << (64 - 12)) b8 -= b9 tmp = b7 ^ b6 b7 = (tmp >> 31) | (tmp << (64 - 31)) b6 -= b7 tmp = b5 ^ b4 b5 = (tmp >> 37) | (tmp << (64 - 37)) b4 -= b5 tmp = b3 ^ b2 b3 = (tmp >> 9) | (tmp << (64 - 9)) b2 -= b3 tmp = b1 ^ b0 b1 = (tmp >> 41) | (tmp << (64 - 41)) b0 -= b1 r-- b0 -= keys[r%17] b1 -= keys[(r+1)%17] b2 -= keys[(r+2)%17] b3 -= keys[(r+3)%17] b4 -= keys[(r+4)%17] b5 -= keys[(r+5)%17] b6 -= keys[(r+6)%17] b7 -= keys[(r+7)%17] b8 -= keys[(r+8)%17] b9 -= keys[(r+9)%17] b10 -= keys[(r+10)%17] b11 -= keys[(r+11)%17] b12 -= keys[(r+12)%17] b13 -= keys[(r+13)%17] + tweak[r%3] b14 -= keys[(r+14)%17] + tweak[(r+1)%3] b15 -= keys[(r+15)%17] + uint64(r) tmp = b7 ^ b12 b7 = (tmp >> 25) | (tmp << (64 - 25)) b12 -= b7 tmp = b3 ^ b10 b3 = (tmp >> 16) | (tmp << (64 - 16)) b10 -= b3 tmp = b5 ^ b8 b5 = (tmp >> 28) | (tmp << (64 - 28)) b8 -= b5 tmp = b1 ^ b14 b1 = (tmp >> 47) | (tmp << (64 - 47)) b14 -= b1 tmp = b9 ^ b4 b9 = (tmp >> 41) | (tmp << (64 - 41)) b4 -= b9 tmp = b13 ^ b6 b13 = (tmp >> 48) | (tmp << (64 - 48)) b6 -= b13 tmp = b11 ^ b2 b11 = (tmp >> 20) | (tmp << (64 - 20)) b2 -= b11 tmp = b15 ^ b0 b15 = (tmp >> 5) | (tmp << (64 - 5)) b0 -= b15 tmp = b9 ^ b10 b9 = (tmp >> 17) | (tmp << (64 - 17)) b10 -= b9 tmp = b11 ^ b8 b11 = (tmp >> 59) | (tmp << (64 - 59)) b8 -= b11 tmp = b13 ^ b14 b13 = (tmp >> 41) | (tmp << (64 - 41)) b14 -= b13 tmp = b15 ^ b12 b15 = (tmp >> 34) | (tmp << (64 - 34)) b12 -= b15 tmp = b1 ^ b6 b1 = (tmp >> 13) | (tmp << (64 - 13)) b6 -= b1 tmp = b3 ^ b4 b3 = (tmp >> 51) | (tmp << (64 - 51)) b4 -= b3 tmp = b5 ^ b2 b5 = (tmp >> 4) | (tmp << (64 - 4)) b2 -= b5 tmp = b7 ^ b0 b7 = (tmp >> 33) | (tmp << (64 - 33)) b0 -= b7 tmp = b1 ^ b8 b1 = (tmp >> 52) | (tmp << (64 - 52)) b8 -= b1 tmp = b5 ^ b14 b5 = (tmp >> 23) | (tmp << (64 - 23)) b14 -= b5 tmp = b3 ^ b12 b3 = (tmp >> 18) | (tmp << (64 - 18)) b12 -= b3 tmp = b7 ^ b10 b7 = (tmp >> 49) | (tmp << (64 - 49)) b10 -= b7 tmp = b15 ^ b4 b15 = (tmp >> 55) | (tmp << (64 - 55)) b4 -= b15 tmp = b11 ^ b6 b11 = (tmp >> 10) | (tmp << (64 - 10)) b6 -= b11 tmp = b13 ^ b2 b13 = (tmp >> 19) | (tmp << (64 - 19)) b2 -= b13 tmp = b9 ^ b0 b9 = (tmp >> 38) | (tmp << (64 - 38)) b0 -= b9 tmp = b15 ^ b14 b15 = (tmp >> 37) | (tmp << (64 - 37)) b14 -= b15 tmp = b13 ^ b12 b13 = (tmp >> 22) | (tmp << (64 - 22)) b12 -= b13 tmp = b11 ^ b10 b11 = (tmp >> 17) | (tmp << (64 - 17)) b10 -= b11 tmp = b9 ^ b8 b9 = (tmp >> 8) | (tmp << (64 - 8)) b8 -= b9 tmp = b7 ^ b6 b7 = (tmp >> 47) | (tmp << (64 - 47)) b6 -= b7 tmp = b5 ^ b4 b5 = (tmp >> 8) | (tmp << (64 - 8)) b4 -= b5 tmp = b3 ^ b2 b3 = (tmp >> 13) | (tmp << (64 - 13)) b2 -= b3 tmp = b1 ^ b0 b1 = (tmp >> 24) | (tmp << (64 - 24)) b0 -= b1 } b0 -= keys[0] b1 -= keys[1] b2 -= keys[2] b3 -= keys[3] b4 -= keys[4] b5 -= keys[5] b6 -= keys[6] b7 -= keys[7] b8 -= keys[8] b9 -= keys[9] b10 -= keys[10] b11 -= keys[11] b12 -= keys[12] b13 -= keys[13] + tweak[0] b14 -= keys[14] + tweak[1] b15 -= keys[15] block[0], block[1], block[2], block[3] = b0, b1, b2, b3 block[4], block[5], block[6], block[7] = b4, b5, b6, b7 block[8], block[9], block[10], block[11] = b8, b9, b10, b11 block[12], block[13], block[14], block[15] = b12, b13, b14, b15 } // UBI1024 does a Threefish1024 encryption of the given block using // the chain values hVal and the tweak. // The chain values are updated through hVal[i] = block[i] ^ Enc(block)[i] func UBI1024(block *[16]uint64, hVal *[17]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3] b4, b5, b6, b7 := block[4], block[5], block[6], block[7] b8, b9, b10, b11 := block[8], block[9], block[10], block[11] b12, b13, b14, b15 := block[12], block[13], block[14], block[15] hVal[16] = C240 ^ hVal[0] ^ hVal[1] ^ hVal[2] ^ hVal[3] ^ hVal[4] ^ hVal[5] ^ hVal[6] ^ hVal[7] ^ hVal[8] ^ hVal[9] ^ hVal[10] ^ hVal[11] ^ hVal[12] ^ hVal[13] ^ hVal[14] ^ hVal[15] tweak[2] = tweak[0] ^ tweak[1] Encrypt1024(block, hVal, tweak) hVal[0] = block[0] ^ b0 hVal[1] = block[1] ^ b1 hVal[2] = block[2] ^ b2 hVal[3] = block[3] ^ b3 hVal[4] = block[4] ^ b4 hVal[5] = block[5] ^ b5 hVal[6] = block[6] ^ b6 hVal[7] = block[7] ^ b7 hVal[8] = block[8] ^ b8 hVal[9] = block[9] ^ b9 hVal[10] = block[10] ^ b10 hVal[11] = block[11] ^ b11 hVal[12] = block[12] ^ b12 hVal[13] = block[13] ^ b13 hVal[14] = block[14] ^ b14 hVal[15] = block[15] ^ b15 } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/threefish/threefish256_ref.go000066400000000000000000000124461520706056300301710ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package threefish func (t *threefish256) Encrypt(dst, src []byte) { var block [4]uint64 bytesToBlock256(&block, src) Encrypt256(&block, &(t.keys), &(t.tweak)) block256ToBytes(dst, &block) } func (t *threefish256) Decrypt(dst, src []byte) { var block [4]uint64 bytesToBlock256(&block, src) Decrypt256(&block, &(t.keys), &(t.tweak)) block256ToBytes(dst, &block) } func newCipher256(tweak *[TweakSize]byte, key []byte) *threefish256 { c := new(threefish256) c.tweak[0] = uint64(tweak[0]) | uint64(tweak[1])<<8 | uint64(tweak[2])<<16 | uint64(tweak[3])<<24 | uint64(tweak[4])<<32 | uint64(tweak[5])<<40 | uint64(tweak[6])<<48 | uint64(tweak[7])<<56 c.tweak[1] = uint64(tweak[8]) | uint64(tweak[9])<<8 | uint64(tweak[10])<<16 | uint64(tweak[11])<<24 | uint64(tweak[12])<<32 | uint64(tweak[13])<<40 | uint64(tweak[14])<<48 | uint64(tweak[15])<<56 c.tweak[2] = c.tweak[0] ^ c.tweak[1] for i := range c.keys[:4] { j := i * 8 c.keys[i] = uint64(key[j]) | uint64(key[j+1])<<8 | uint64(key[j+2])<<16 | uint64(key[j+3])<<24 | uint64(key[j+4])<<32 | uint64(key[j+5])<<40 | uint64(key[j+6])<<48 | uint64(key[j+7])<<56 } c.keys[4] = C240 ^ c.keys[0] ^ c.keys[1] ^ c.keys[2] ^ c.keys[3] return c } // Encrypt256 encrypts the 4 words of block using the expanded 256 bit key and // the 128 bit tweak. The keys[4] must be keys[0] xor keys[1] xor ... keys[3] xor C240. // The tweak[2] must be tweak[0] xor tweak[1]. func Encrypt256(block *[4]uint64, keys *[5]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3] for r := 0; r < 17; r++ { b0 += keys[r%5] b1 += keys[(r+1)%5] + tweak[r%3] b2 += keys[(r+2)%5] + tweak[(r+1)%3] b3 += keys[(r+3)%5] + uint64(r) b0 += b1 b1 = ((b1 << 14) | (b1 >> (64 - 14))) ^ b0 b2 += b3 b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b2 b0 += b3 b3 = ((b3 << 52) | (b3 >> (64 - 52))) ^ b0 b2 += b1 b1 = ((b1 << 57) | (b1 >> (64 - 57))) ^ b2 b0 += b1 b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b0 b2 += b3 b3 = ((b3 << 40) | (b3 >> (64 - 40))) ^ b2 b0 += b3 b3 = ((b3 << 5) | (b3 >> (64 - 5))) ^ b0 b2 += b1 b1 = ((b1 << 37) | (b1 >> (64 - 37))) ^ b2 r++ b0 += keys[r%5] b1 += keys[(r+1)%5] + tweak[r%3] b2 += keys[(r+2)%5] + tweak[(r+1)%3] b3 += keys[(r+3)%5] + uint64(r) b0 += b1 b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b0 b2 += b3 b3 = ((b3 << 33) | (b3 >> (64 - 33))) ^ b2 b0 += b3 b3 = ((b3 << 46) | (b3 >> (64 - 46))) ^ b0 b2 += b1 b1 = ((b1 << 12) | (b1 >> (64 - 12))) ^ b2 b0 += b1 b1 = ((b1 << 58) | (b1 >> (64 - 58))) ^ b0 b2 += b3 b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b2 b0 += b3 b3 = ((b3 << 32) | (b3 >> (64 - 32))) ^ b0 b2 += b1 b1 = ((b1 << 32) | (b1 >> (64 - 32))) ^ b2 } b0 += keys[3] b1 += keys[4] + tweak[0] b2 += keys[0] + tweak[1] b3 += keys[1] + uint64(18) block[0], block[1], block[2], block[3] = b0, b1, b2, b3 } // Decrypt256 decrypts the 4 words of block using the expanded 256 bit key and // the 128 bit tweak. The keys[4] must be keys[0] xor keys[1] xor ... keys[3] xor C240. // The tweak[2] must be tweak[0] xor tweak[1]. func Decrypt256(block *[4]uint64, keys *[5]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3] var tmp uint64 for r := 18; r > 1; r-- { b0 -= keys[r%5] b1 -= keys[(r+1)%5] + tweak[r%3] b2 -= keys[(r+2)%5] + tweak[(r+1)%3] b3 -= keys[(r+3)%5] + uint64(r) tmp = b1 ^ b2 b1 = (tmp >> 32) | (tmp << (64 - 32)) b2 -= b1 tmp = b3 ^ b0 b3 = (tmp >> 32) | (tmp << (64 - 32)) b0 -= b3 tmp = b3 ^ b2 b3 = (tmp >> 22) | (tmp << (64 - 22)) b2 -= b3 tmp = b1 ^ b0 b1 = (tmp >> 58) | (tmp << (64 - 58)) b0 -= b1 tmp = b1 ^ b2 b1 = (tmp >> 12) | (tmp << (64 - 12)) b2 -= b1 tmp = b3 ^ b0 b3 = (tmp >> 46) | (tmp << (64 - 46)) b0 -= b3 tmp = b3 ^ b2 b3 = (tmp >> 33) | (tmp << (64 - 33)) b2 -= b3 tmp = b1 ^ b0 b1 = (tmp >> 25) | (tmp << (64 - 25)) b0 -= b1 r-- b0 -= keys[r%5] b1 -= keys[(r+1)%5] + tweak[r%3] b2 -= keys[(r+2)%5] + tweak[(r+1)%3] b3 -= keys[(r+3)%5] + uint64(r) tmp = b1 ^ b2 b1 = (tmp >> 37) | (tmp << (64 - 37)) b2 -= b1 tmp = b3 ^ b0 b3 = (tmp >> 5) | (tmp << (64 - 5)) b0 -= b3 tmp = b3 ^ b2 b3 = (tmp >> 40) | (tmp << (64 - 40)) b2 -= b3 tmp = b1 ^ b0 b1 = (tmp >> 23) | (tmp << (64 - 23)) b0 -= b1 tmp = b1 ^ b2 b1 = (tmp >> 57) | (tmp << (64 - 57)) b2 -= b1 tmp = b3 ^ b0 b3 = (tmp >> 52) | (tmp << (64 - 52)) b0 -= b3 tmp = b3 ^ b2 b3 = (tmp >> 16) | (tmp << (64 - 16)) b2 -= b3 tmp = b1 ^ b0 b1 = (tmp >> 14) | (tmp << (64 - 14)) b0 -= b1 } b0 -= keys[0] b1 -= keys[1] + tweak[0] b2 -= keys[2] + tweak[1] b3 -= keys[3] block[0], block[1], block[2], block[3] = b0, b1, b2, b3 } // UBI256 does a Threefish256 encryption of the given block using // the chain values hVal and the tweak. // The chain values are updated through hVal[i] = block[i] ^ Enc(block)[i] func UBI256(block *[4]uint64, hVal *[5]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3] hVal[4] = C240 ^ hVal[0] ^ hVal[1] ^ hVal[2] ^ hVal[3] tweak[2] = tweak[0] ^ tweak[1] Encrypt256(block, hVal, tweak) hVal[0] = block[0] ^ b0 hVal[1] = block[1] ^ b1 hVal[2] = block[2] ^ b2 hVal[3] = block[3] ^ b3 } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/threefish/threefish512_ref.go000066400000000000000000000167761520706056300301760ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package threefish func (t *threefish512) Encrypt(dst, src []byte) { var block [8]uint64 bytesToBlock512(&block, src) Encrypt512(&block, &(t.keys), &(t.tweak)) block512ToBytes(dst, &block) } func (t *threefish512) Decrypt(dst, src []byte) { var block [8]uint64 bytesToBlock512(&block, src) Decrypt512(&block, &(t.keys), &(t.tweak)) block512ToBytes(dst, &block) } func newCipher512(tweak *[TweakSize]byte, key []byte) *threefish512 { c := new(threefish512) c.tweak[0] = uint64(tweak[0]) | uint64(tweak[1])<<8 | uint64(tweak[2])<<16 | uint64(tweak[3])<<24 | uint64(tweak[4])<<32 | uint64(tweak[5])<<40 | uint64(tweak[6])<<48 | uint64(tweak[7])<<56 c.tweak[1] = uint64(tweak[8]) | uint64(tweak[9])<<8 | uint64(tweak[10])<<16 | uint64(tweak[11])<<24 | uint64(tweak[12])<<32 | uint64(tweak[13])<<40 | uint64(tweak[14])<<48 | uint64(tweak[15])<<56 c.tweak[2] = c.tweak[0] ^ c.tweak[1] for i := range c.keys[:8] { j := i * 8 c.keys[i] = uint64(key[j]) | uint64(key[j+1])<<8 | uint64(key[j+2])<<16 | uint64(key[j+3])<<24 | uint64(key[j+4])<<32 | uint64(key[j+5])<<40 | uint64(key[j+6])<<48 | uint64(key[j+7])<<56 } c.keys[8] = C240 ^ c.keys[0] ^ c.keys[1] ^ c.keys[2] ^ c.keys[3] ^ c.keys[4] ^ c.keys[5] ^ c.keys[6] ^ c.keys[7] return c } // Encrypt512 encrypts the 8 words of block using the expanded 512 bit key and // the 128 bit tweak. The keys[8] must be keys[0] xor keys[1] xor ... keys[8] xor C240. // The tweak[2] must be tweak[0] xor tweak[1]. func Encrypt512(block *[8]uint64, keys *[9]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3] b4, b5, b6, b7 := block[4], block[5], block[6], block[7] for r := 0; r < 17; r++ { b0 += keys[r%9] b1 += keys[(r+1)%9] b2 += keys[(r+2)%9] b3 += keys[(r+3)%9] b4 += keys[(r+4)%9] b5 += keys[(r+5)%9] + tweak[r%3] b6 += keys[(r+6)%9] + tweak[(r+1)%3] b7 += keys[(r+7)%9] + uint64(r) b0 += b1 b1 = (b1<<46 | b1>>(64-46)) ^ b0 b2 += b3 b3 = (b3<<36 | b3>>(64-36)) ^ b2 b4 += b5 b5 = (b5<<19 | b5>>(64-19)) ^ b4 b6 += b7 b7 = (b7<<37 | b7>>(64-37)) ^ b6 b2 += b1 b1 = (b1<<33 | b1>>(64-33)) ^ b2 b4 += b7 b7 = (b7<<27 | b7>>(64-27)) ^ b4 b6 += b5 b5 = (b5<<14 | b5>>(64-14)) ^ b6 b0 += b3 b3 = (b3<<42 | b3>>(64-42)) ^ b0 b4 += b1 b1 = (b1<<17 | b1>>(64-17)) ^ b4 b6 += b3 b3 = (b3<<49 | b3>>(64-49)) ^ b6 b0 += b5 b5 = (b5<<36 | b5>>(64-36)) ^ b0 b2 += b7 b7 = (b7<<39 | b7>>(64-39)) ^ b2 b6 += b1 b1 = (b1<<44 | b1>>(64-44)) ^ b6 b0 += b7 b7 = (b7<<9 | b7>>(64-9)) ^ b0 b2 += b5 b5 = (b5<<54 | b5>>(64-54)) ^ b2 b4 += b3 b3 = (b3<<56 | b3>>(64-56)) ^ b4 r++ b0 += keys[r%9] b1 += keys[(r+1)%9] b2 += keys[(r+2)%9] b3 += keys[(r+3)%9] b4 += keys[(r+4)%9] b5 += keys[(r+5)%9] + tweak[r%3] b6 += keys[(r+6)%9] + tweak[(r+1)%3] b7 += keys[(r+7)%9] + uint64(r) b0 += b1 b1 = (b1<<39 | b1>>(64-39)) ^ b0 b2 += b3 b3 = (b3<<30 | b3>>(64-30)) ^ b2 b4 += b5 b5 = (b5<<34 | b5>>(64-34)) ^ b4 b6 += b7 b7 = (b7<<24 | b7>>(64-24)) ^ b6 b2 += b1 b1 = (b1<<13 | b1>>(64-13)) ^ b2 b4 += b7 b7 = (b7<<50 | b7>>(64-50)) ^ b4 b6 += b5 b5 = (b5<<10 | b5>>(64-10)) ^ b6 b0 += b3 b3 = (b3<<17 | b3>>(64-17)) ^ b0 b4 += b1 b1 = (b1<<25 | b1>>(64-25)) ^ b4 b6 += b3 b3 = (b3<<29 | b3>>(64-29)) ^ b6 b0 += b5 b5 = (b5<<39 | b5>>(64-39)) ^ b0 b2 += b7 b7 = (b7<<43 | b7>>(64-43)) ^ b2 b6 += b1 b1 = (b1<<8 | b1>>(64-8)) ^ b6 b0 += b7 b7 = (b7<<35 | b7>>(64-35)) ^ b0 b2 += b5 b5 = (b5<<56 | b5>>(64-56)) ^ b2 b4 += b3 b3 = (b3<<22 | b3>>(64-22)) ^ b4 } b0 += keys[0] b1 += keys[1] b2 += keys[2] b3 += keys[3] b4 += keys[4] b5 += keys[5] + tweak[0] b6 += keys[6] + tweak[1] b7 += keys[7] + 18 block[0], block[1], block[2], block[3] = b0, b1, b2, b3 block[4], block[5], block[6], block[7] = b4, b5, b6, b7 } // Decrypt512 decrypts the 8 words of block using the expanded 512 bit key and // the 128 bit tweak. The keys[8] must be keys[0] xor keys[1] xor ... keys[8] xor C240. // The tweak[2] must be tweak[0] xor tweak[1]. func Decrypt512(block *[8]uint64, keys *[9]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3] b4, b5, b6, b7 := block[4], block[5], block[6], block[7] var tmp uint64 for r := 18; r > 1; r-- { b0 -= keys[r%9] b1 -= keys[(r+1)%9] b2 -= keys[(r+2)%9] b3 -= keys[(r+3)%9] b4 -= keys[(r+4)%9] b5 -= keys[(r+5)%9] + tweak[r%3] b6 -= keys[(r+6)%9] + tweak[(r+1)%3] b7 -= keys[(r+7)%9] + uint64(r) tmp = b3 ^ b4 b3 = tmp>>22 | tmp<<(64-22) b4 -= b3 tmp = b5 ^ b2 b5 = tmp>>56 | tmp<<(64-56) b2 -= b5 tmp = b7 ^ b0 b7 = tmp>>35 | tmp<<(64-35) b0 -= b7 tmp = b1 ^ b6 b1 = tmp>>8 | tmp<<(64-8) b6 -= b1 tmp = b7 ^ b2 b7 = tmp>>43 | tmp<<(64-43) b2 -= b7 tmp = b5 ^ b0 b5 = tmp>>39 | tmp<<(64-39) b0 -= b5 tmp = b3 ^ b6 b3 = tmp>>29 | tmp<<(64-29) b6 -= b3 tmp = b1 ^ b4 b1 = tmp>>25 | tmp<<(64-25) b4 -= b1 tmp = b3 ^ b0 b3 = tmp>>17 | tmp<<(64-17) b0 -= b3 tmp = b5 ^ b6 b5 = tmp>>10 | tmp<<(64-10) b6 -= b5 tmp = b7 ^ b4 b7 = tmp>>50 | tmp<<(64-50) b4 -= b7 tmp = b1 ^ b2 b1 = tmp>>13 | tmp<<(64-13) b2 -= b1 tmp = b7 ^ b6 b7 = tmp>>24 | tmp<<(64-24) b6 -= b7 tmp = b5 ^ b4 b5 = tmp>>34 | tmp<<(64-34) b4 -= b5 tmp = b3 ^ b2 b3 = tmp>>30 | tmp<<(64-30) b2 -= b3 tmp = b1 ^ b0 b1 = tmp>>39 | tmp<<(64-39) b0 -= b1 r-- b0 -= keys[r%9] b1 -= keys[(r+1)%9] b2 -= keys[(r+2)%9] b3 -= keys[(r+3)%9] b4 -= keys[(r+4)%9] b5 -= keys[(r+5)%9] + tweak[r%3] b6 -= keys[(r+6)%9] + tweak[(r+1)%3] b7 -= keys[(r+7)%9] + uint64(r) tmp = b3 ^ b4 b3 = tmp>>56 | tmp<<(64-56) b4 -= b3 tmp = b5 ^ b2 b5 = tmp>>54 | tmp<<(64-54) b2 -= b5 tmp = b7 ^ b0 b7 = tmp>>9 | tmp<<(64-9) b0 -= b7 tmp = b1 ^ b6 b1 = tmp>>44 | tmp<<(64-44) b6 -= b1 tmp = b7 ^ b2 b7 = tmp>>39 | tmp<<(64-39) b2 -= b7 tmp = b5 ^ b0 b5 = tmp>>36 | tmp<<(64-36) b0 -= b5 tmp = b3 ^ b6 b3 = tmp>>49 | tmp<<(64-49) b6 -= b3 tmp = b1 ^ b4 b1 = tmp>>17 | tmp<<(64-17) b4 -= b1 tmp = b3 ^ b0 b3 = tmp>>42 | tmp<<(64-42) b0 -= b3 tmp = b5 ^ b6 b5 = tmp>>14 | tmp<<(64-14) b6 -= b5 tmp = b7 ^ b4 b7 = tmp>>27 | tmp<<(64-27) b4 -= b7 tmp = b1 ^ b2 b1 = tmp>>33 | tmp<<(64-33) b2 -= b1 tmp = b7 ^ b6 b7 = tmp>>37 | tmp<<(64-37) b6 -= b7 tmp = b5 ^ b4 b5 = tmp>>19 | tmp<<(64-19) b4 -= b5 tmp = b3 ^ b2 b3 = tmp>>36 | tmp<<(64-36) b2 -= b3 tmp = b1 ^ b0 b1 = tmp>>46 | tmp<<(64-46) b0 -= b1 } b0 -= keys[0] b1 -= keys[1] b2 -= keys[2] b3 -= keys[3] b4 -= keys[4] b5 -= keys[5] + tweak[0] b6 -= keys[6] + tweak[1] b7 -= keys[7] block[0], block[1], block[2], block[3] = b0, b1, b2, b3 block[4], block[5], block[6], block[7] = b4, b5, b6, b7 } // UBI512 does a Threefish512 encryption of the given block using // the chain values hVal and the tweak. // The chain values are updated through hVal[i] = block[i] ^ Enc(block)[i] func UBI512(block *[8]uint64, hVal *[9]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3] b4, b5, b6, b7 := block[4], block[5], block[6], block[7] hVal[8] = C240 ^ hVal[0] ^ hVal[1] ^ hVal[2] ^ hVal[3] ^ hVal[4] ^ hVal[5] ^ hVal[6] ^ hVal[7] tweak[2] = tweak[0] ^ tweak[1] Encrypt512(block, hVal, tweak) hVal[0] = block[0] ^ b0 hVal[1] = block[1] ^ b1 hVal[2] = block[2] ^ b2 hVal[3] = block[3] ^ b3 hVal[4] = block[4] ^ b4 hVal[5] = block[5] ^ b5 hVal[6] = block[6] ^ b6 hVal[7] = block[7] ^ b7 } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/threefish/threefish_amd64.go000066400000000000000000000037741520706056300300770ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // +build amd64 package threefish import "unsafe" func bytesToBlock256(block *[4]uint64, src []byte) { srcPtr := (*[4]uint64)(unsafe.Pointer(&src[0])) block[0] = srcPtr[0] block[1] = srcPtr[1] block[2] = srcPtr[2] block[3] = srcPtr[3] } func block256ToBytes(dst []byte, block *[4]uint64) { dstPtr := (*[4]uint64)(unsafe.Pointer(&dst[0])) dstPtr[0] = block[0] dstPtr[1] = block[1] dstPtr[2] = block[2] dstPtr[3] = block[3] } func bytesToBlock512(block *[8]uint64, src []byte) { srcPtr := (*[8]uint64)(unsafe.Pointer(&src[0])) block[0] = srcPtr[0] block[1] = srcPtr[1] block[2] = srcPtr[2] block[3] = srcPtr[3] block[4] = srcPtr[4] block[5] = srcPtr[5] block[6] = srcPtr[6] block[7] = srcPtr[7] } func block512ToBytes(dst []byte, block *[8]uint64) { dstPtr := (*[8]uint64)(unsafe.Pointer(&dst[0])) dstPtr[0] = block[0] dstPtr[1] = block[1] dstPtr[2] = block[2] dstPtr[3] = block[3] dstPtr[4] = block[4] dstPtr[5] = block[5] dstPtr[6] = block[6] dstPtr[7] = block[7] } func bytesToBlock1024(block *[16]uint64, src []byte) { srcPtr := (*[16]uint64)(unsafe.Pointer(&src[0])) block[0] = srcPtr[0] block[1] = srcPtr[1] block[2] = srcPtr[2] block[3] = srcPtr[3] block[4] = srcPtr[4] block[5] = srcPtr[5] block[6] = srcPtr[6] block[7] = srcPtr[7] block[8] = srcPtr[8] block[9] = srcPtr[9] block[10] = srcPtr[10] block[11] = srcPtr[11] block[12] = srcPtr[12] block[13] = srcPtr[13] block[14] = srcPtr[14] block[15] = srcPtr[15] } func block1024ToBytes(dst []byte, block *[16]uint64) { dstPtr := (*[16]uint64)(unsafe.Pointer(&dst[0])) dstPtr[0] = block[0] dstPtr[1] = block[1] dstPtr[2] = block[2] dstPtr[3] = block[3] dstPtr[4] = block[4] dstPtr[5] = block[5] dstPtr[6] = block[6] dstPtr[7] = block[7] dstPtr[8] = block[8] dstPtr[9] = block[9] dstPtr[10] = block[10] dstPtr[11] = block[11] dstPtr[12] = block[12] dstPtr[13] = block[13] dstPtr[14] = block[14] dstPtr[15] = block[15] } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/threefish/threefish_ref.go000066400000000000000000000035711520706056300277330ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file // +build !amd64 package threefish func bytesToBlock256(block *[4]uint64, src []byte) { for i := range block { j := i * 8 block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | uint64(src[j+3])<<24 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 } } func block256ToBytes(dst []byte, block *[4]uint64) { for i, v := range block { j := i * 8 dst[j] = byte(v) dst[j+1] = byte(v >> 8) dst[j+2] = byte(v >> 16) dst[j+3] = byte(v >> 24) dst[j+4] = byte(v >> 32) dst[j+5] = byte(v >> 40) dst[j+6] = byte(v >> 48) dst[j+7] = byte(v >> 56) } } func bytesToBlock512(block *[8]uint64, src []byte) { for i := range block { j := i * 8 block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | uint64(src[j+3])<<24 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 } } func block512ToBytes(dst []byte, block *[8]uint64) { for i, v := range block { j := i * 8 dst[j] = byte(v) dst[j+1] = byte(v >> 8) dst[j+2] = byte(v >> 16) dst[j+3] = byte(v >> 24) dst[j+4] = byte(v >> 32) dst[j+5] = byte(v >> 40) dst[j+6] = byte(v >> 48) dst[j+7] = byte(v >> 56) } } func bytesToBlock1024(block *[16]uint64, src []byte) { for i := range block { j := i * 8 block[i] = uint64(src[j]) | uint64(src[j+1])<<8 | uint64(src[j+2])<<16 | uint64(src[j+3])<<24 | uint64(src[j+4])<<32 | uint64(src[j+5])<<40 | uint64(src[j+6])<<48 | uint64(src[j+7])<<56 } } func block1024ToBytes(dst []byte, block *[16]uint64) { for i, v := range block { j := i * 8 dst[j] = byte(v) dst[j+1] = byte(v >> 8) dst[j+2] = byte(v >> 16) dst[j+3] = byte(v >> 24) dst[j+4] = byte(v >> 32) dst[j+5] = byte(v >> 40) dst[j+6] = byte(v >> 48) dst[j+7] = byte(v >> 56) } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/threefish/threefish_test.go000066400000000000000000000066641520706056300301440ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package threefish import "testing" // The UBI256, UBI512 and UBI1024 functions are tested within // the skein packages (skein, skein256 and skein1024) func testBlockSize(t *testing.T, blocksize int) { var tweak [TweakSize]byte c, err := NewCipher(&tweak, make([]byte, blocksize)) if err != nil { t.Fatalf("Failed to create Threefish-%d instance: %s", blocksize*8, err) } if bs := c.BlockSize(); bs != blocksize { t.Fatalf("BlockSize() returned unexpected value: %d - expected %d", bs, blocksize) } } func TestBlockSize(t *testing.T) { testBlockSize(t, BlockSize256) testBlockSize(t, BlockSize512) testBlockSize(t, BlockSize1024) } func TestNew(t *testing.T) { badKeyLengths := []int{ 0, 31, 33, 63, 65, 127, 129, } var tweak [TweakSize]byte for i, v := range badKeyLengths { _, err := NewCipher(&tweak, make([]byte, v)) if err == nil { t.Fatalf("BadKey %d: NewCipher accepted inavlid key length %d", i, v) } } } func TestIncrementTweak(t *testing.T) { var tweak [3]uint64 IncrementTweak(&tweak, 1) if tweak[0] != 1 { t.Fatalf("IncrementTweak failed by increment of %d", 1) } tweak[0] = ^uint64(0) IncrementTweak(&tweak, 2) if tweak[0] != 1 && tweak[1] != 1 { t.Fatalf("IncrementTweak failed by increment of %d", 2) } tweak[0] = ^uint64(0) tweak[1] = uint64(0xFFFFFFFF) IncrementTweak(&tweak, 1) if tweak[0] != 0 && tweak[1] != 0 { t.Fatalf("IncrementTweak failed by increment of %d", 1) } } // Benchmarks func benchmarkEncrypt(b *testing.B, blocksize, size int) { key := make([]byte, blocksize) var tweak [TweakSize]byte c, err := NewCipher(&tweak, key) if err != nil { b.Fatalf("Failed to create Threefish-%d instance: %s", blocksize*8, err) } n := size / blocksize buf := make([]byte, blocksize) b.SetBytes(int64(blocksize * n)) b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < n; j++ { c.Encrypt(buf, buf) } } } func benchmarkDecrypt(b *testing.B, blocksize, size int) { key := make([]byte, blocksize) var tweak [TweakSize]byte c, err := NewCipher(&tweak, key) if err != nil { b.Fatalf("Failed to create Threefish-%d instance: %s", blocksize*8, err) } n := size / blocksize buf := make([]byte, blocksize) b.SetBytes(int64(blocksize * n)) b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < n; j++ { c.Decrypt(buf, buf) } } } func BenchmarkEncrypt256_32(b *testing.B) { benchmarkEncrypt(b, BlockSize256, 32) } func BenchmarkEncrypt256_1024(b *testing.B) { benchmarkEncrypt(b, BlockSize256, 1024) } func BenchmarkEncrypt512_64(b *testing.B) { benchmarkEncrypt(b, BlockSize512, 64) } func BenchmarkEncrypt512_1024(b *testing.B) { benchmarkEncrypt(b, BlockSize512, 1024) } func BenchmarkEncrypt1024_128(b *testing.B) { benchmarkEncrypt(b, BlockSize1024, 128) } func BenchmarkEncrypt1024_1024(b *testing.B) { benchmarkEncrypt(b, BlockSize1024, 1024) } func BenchmarkDecrypt256_32(b *testing.B) { benchmarkDecrypt(b, BlockSize256, 32) } func BenchmarkDecrypt256_1024(b *testing.B) { benchmarkDecrypt(b, BlockSize256, 1024) } func BenchmarkDecrypt512_64(b *testing.B) { benchmarkDecrypt(b, BlockSize512, 64) } func BenchmarkDecrypt512_1024(b *testing.B) { benchmarkDecrypt(b, BlockSize512, 1024) } func BenchmarkDecrypt1024_128(b *testing.B) { benchmarkDecrypt(b, BlockSize1024, 128) } func BenchmarkDecrypt1024_1024(b *testing.B) { benchmarkDecrypt(b, BlockSize1024, 1024) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/threefish/vectors_test.go000066400000000000000000000147471520706056300276510ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package threefish import ( "bytes" "encoding/hex" "testing" ) func fromHex(s string) []byte { b, err := hex.DecodeString(s) if err != nil { panic(err) } return b } var testVectors256 = []struct { key, tweak, plaintext, ciphertext string }{ { key: "0000000000000000000000000000000000000000000000000000000000000000", tweak: "00000000000000000000000000000000", plaintext: "0000000000000000000000000000000000000000000000000000000000000000", ciphertext: "84da2a1f8beaee947066ae3e3103f1ad536db1f4a1192495116b9f3ce6133fd8", }, { key: "101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f", tweak: "000102030405060708090a0b0c0d0e0f", plaintext: "FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0", ciphertext: "e0d091ff0eea8fdfc98192e62ed80ad59d865d08588df476657056b5955e97df", }, } func TestVectros256(t *testing.T) { for i, v := range testVectors256 { key := fromHex(v.key) tweak := fromHex(v.tweak) plaintext := fromHex(v.plaintext) ciphertext := fromHex(v.ciphertext) var Tweak [TweakSize]byte copy(Tweak[:], tweak) c, err := NewCipher(&Tweak, key) if err != nil { t.Fatal(err) } dst := make([]byte, BlockSize256) c.Encrypt(dst, plaintext) if !bytes.Equal(ciphertext, dst) { t.Fatalf("Test vector %d : Encryption failed\nFound: %s \nExpected: %s", i, hex.EncodeToString(dst), hex.EncodeToString(ciphertext)) } c.Decrypt(dst, dst) if !bytes.Equal(plaintext, dst) { t.Fatalf("Test vector %d : Decryption failed\nFound: %s \nExpected: %s", i, hex.EncodeToString(dst), hex.EncodeToString(plaintext)) } } } // Test vectors from: // https://github.com/bcgit/bc-java/blob/master/core/src/test/java/org/bouncycastle/crypto/test/Threefish512Test.java var testVectors512 = []struct { key, tweak, plaintext, ciphertext string }{ { key: "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000", tweak: "00000000000000000000000000000000", plaintext: "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000", ciphertext: "b1a2bbc6ef6025bc40eb3822161f36e375d1bb0aee3186fbd19e47c5d479947b" + "7bc2f8586e35f0cff7e7f03084b0b7b1f1ab3961a580a3e97eb41ea14a6d7bbe", }, { key: "101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f", tweak: "000102030405060708090a0b0c0d0e0f", plaintext: "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0" + "dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0", ciphertext: "e304439626d45a2cb401cad8d636249a6338330eb06d45dd8b36b90e97254779" + "272a0a8d99463504784420ea18c9a725af11dffea10162348927673d5c1caf3d", }, } func TestVectros512(t *testing.T) { for i, v := range testVectors512 { key := fromHex(v.key) tweak := fromHex(v.tweak) plaintext := fromHex(v.plaintext) ciphertext := fromHex(v.ciphertext) var Tweak [TweakSize]byte copy(Tweak[:], tweak) c, err := NewCipher(&Tweak, key) if err != nil { t.Fatal(err) } dst := make([]byte, BlockSize512) c.Encrypt(dst, plaintext) if !bytes.Equal(ciphertext, dst) { t.Fatalf("Test vector %d : Encryption failed\nFound: %s \nExpected: %s", i, hex.EncodeToString(dst), hex.EncodeToString(ciphertext)) } c.Decrypt(dst, dst) if !bytes.Equal(plaintext, dst) { t.Fatalf("Test vector %d : Decryption failed\nFound: %s \nExpected: %s", i, hex.EncodeToString(dst), hex.EncodeToString(plaintext)) } } } // Test vectors from: // https://github.com/bcgit/bc-java/blob/master/core/src/test/java/org/bouncycastle/crypto/test/Threefish1024Test.java var testVectors1024 = []struct { key, tweak, plaintext, ciphertext string }{ { key: "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000", tweak: "00000000000000000000000000000000", plaintext: "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000", ciphertext: "f05c3d0a3d05b304f785ddc7d1e036015c8aa76e2f217b06c6e1544c0bc1a90d" + "f0accb9473c24e0fd54fea68057f43329cb454761d6df5cf7b2e9b3614fbd5a2" + "0b2e4760b40603540d82eabc5482c171c832afbe68406bc39500367a592943fa" + "9a5b4a43286ca3c4cf46104b443143d560a4b230488311df4feef7e1dfe8391e", }, { key: "101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f" + "505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f" + "707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f", tweak: "000102030405060708090a0b0c0d0e0f", plaintext: "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0" + "dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0" + "bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a0" + "9f9e9d9c9b9a999897969594939291908f8e8d8c8b8a89888786858483828180", ciphertext: "a6654ddbd73cc3b05dd777105aa849bce49372eaaffc5568d254771bab85531c" + "94f780e7ffaae430d5d8af8c70eebbe1760f3b42b737a89cb363490d670314bd" + "8aa41ee63c2e1f45fbd477922f8360b388d6125ea6c7af0ad7056d01796e90c8" + "3313f4150a5716b30ed5f569288ae974ce2b4347926fce57de44512177dd7cde", }, } func TestVectros1024(t *testing.T) { for i, v := range testVectors1024 { key := fromHex(v.key) tweak := fromHex(v.tweak) plaintext := fromHex(v.plaintext) ciphertext := fromHex(v.ciphertext) var Tweak [TweakSize]byte copy(Tweak[:], tweak) c, err := NewCipher(&Tweak, key) if err != nil { t.Fatal(err) } dst := make([]byte, BlockSize1024) c.Encrypt(dst, plaintext) if !bytes.Equal(ciphertext, dst) { t.Fatalf("Test vector %d : Encryption failed\nFound: %s \nExpected: %s", i, hex.EncodeToString(dst), hex.EncodeToString(ciphertext)) } c.Decrypt(dst, dst) if !bytes.Equal(plaintext, dst) { t.Fatalf("Test vector %d : Decryption failed\nFound: %s \nExpected: %s", i, hex.EncodeToString(dst), hex.EncodeToString(plaintext)) } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/skein/vector_test.go000066400000000000000000000126131520706056300254730ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file package skein import ( "bytes" "encoding/hex" "testing" ) func fromHex(s string) []byte { b, err := hex.DecodeString(s) if err != nil { panic(err) } return b } var testVectors = []struct { hashsize int conf *Config msg, hash string }{ { hashsize: 64, conf: nil, msg: "", hash: "BC5B4C50925519C290CC634277AE3D6257212395CBA733BBAD37A4AF0FA06AF4" + "1FCA7903D06564FEA7A2D3730DBDB80C1F85562DFCC070334EA4D1D9E72CBA7A", }, { hashsize: 64, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB", hash: "02D01535C2DF280FDE92146DF054B0609273C73056C93B94B82F5E7DCC5BE697" + "9978C4BE24331CAA85D892D2E710C6C9B4904CD056A53547B866BEE097C0FB17", }, { hashsize: 20, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "EF03079D61B57C6047E15FA2B35B46FA24279539", }, { hashsize: 32, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "809DD3F763A11AF90912BBB92BC0D94361CBADAB10142992000C88B4CEB88648", }, { hashsize: 48, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "825F5CBD5DA8807A7B4D3E7BD9CD089CA3A256BCC064CD73A9355BF3AE67F2BF" + "93AC7074B3B19907A0665BA3A878B262", }, { hashsize: 64, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "1A0D5ABF4432E7C612D658F8DCFA35B0D1AB68B8D6BD4DD115C23CC57B5C5BCD" + "DE9BFF0ECE4208596E499F211BC07594D0CB6F3C12B0E110174B2A9B4B2CB6A9", }, { hashsize: 128, conf: nil, msg: "FBD17C26B61A82E12E125F0D459B96C91AB4837DFF22B39B78439430CDFC5DC8" + "78BB393A1A5F79BEF30995A85A12923339BA8AB7D8FC6DC5FEC6F4ED22C122BB" + "E7EB61981892966DE5CEF576F71FC7A80D14DAB2D0C03940B95B9FB3A727C66A" + "6E1FF0DC311B9AA21A3054484802154C1826C2A27A0914152AEB76F1168D4410", hash: "8C25D314110D1C0D58054C96A19D571E26A45D5362AA8F47547E53E0BE4A830A" + "5F2C29CCD88E2185FEBAD024A4696F2DBE8307DC150E7A58B3793B1A93FAE252" + "3E2D239C59A23A1CC127B3C481A9809162E60B4CB01C011B9630322C8FE9745D" + "56D0F3AED54B3490578DB4692901EAFC1960C15359176A9C0990B32B8CA8F94B", }, { hashsize: 64, conf: &Config{Key: fromHex("")}, msg: "D3090C72", hash: "1259AFC2CB025EEF2F681E128F889BBCE57F9A502D57D1A17239A12E71603559" + "16B72223790FD9A8B367EC96212A3ED239331ED72EF3DEB17685A8D5FD75158D", }, { hashsize: 64, conf: &Config{Key: fromHex("CB41F1706CDE09651203C2D0EFBADDF847A0D315CB2E53FF8BAC41DA0002672E" + "920244C66E02D5F0DAD3E94C42BB65F0D14157DECF4105EF5609D5B0984457C1")}, msg: "D3090C72167517F7C7AD82A70C2FD3F6", hash: "478D7B6C0CC6E35D9EBBDEDF39128E5A36585DB6222891692D1747D401DE34CE" + "3DB6FCBAB6C968B7F2620F4A844A2903B547775579993736D2493A75FF6752A1", }, } func TestVectors(t *testing.T) { for i, v := range testVectors { conf, msg, ref := v.conf, fromHex(v.msg), fromHex(v.hash) h := New(v.hashsize, conf) h.Write(msg) sum := h.Sum(nil) if !bytes.Equal(sum, ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(ref)) } sum = Sum(msg, v.hashsize, conf) if !bytes.Equal(sum, ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(sum), hex.EncodeToString(ref)) } var key []byte if conf != nil { key = conf.Key } switch v.hashsize { case 64: { var out [64]byte Sum512(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } case 48: { var out [48]byte Sum384(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } case 32: { var out [32]byte Sum256(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } case 20: { var out [20]byte Sum160(&out, msg, key) if !bytes.Equal(out[:], ref) { t.Fatalf("Test vector %d : Hash does not match:\nFound: %s\nExpected: %s", i, hex.EncodeToString(out[:]), hex.EncodeToString(ref)) } } } } } golang-github-enceve-crypto-0.0~git20160707.34d48bb/xor.go000066400000000000000000000007511520706056300226310ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build !amd64 package crypto // XOR xors the bytes in src and with and writes the result to dst. // The destination is assumed to have enough space. Returns the // number of bytes xor'd. func XOR(dst, src, with []byte) int { var a, b []byte if len(src) <= len(with) { a = src b = with } else { b = src a = with } for i, v := range a { dst[i] = b[i] ^ v } return len(a) } golang-github-enceve-crypto-0.0~git20160707.34d48bb/xor_amd64.go000066400000000000000000000014431520706056300236230ustar00rootroot00000000000000// Use of this source code is governed by a license // that can be found in the LICENSE file. // +build amd64, !cgo, !appengine package crypto import "unsafe" const wordSize = int(unsafe.Sizeof(uintptr(0))) // XOR xors the bytes in src and with and writes the result to dst. // The destination is assumed to have enough space. Returns the // number of bytes xor'd. func XOR(dst, src, with []byte) int { n := len(src) if len(with) < n { n = len(with) } w := n / wordSize if w > 0 { dstPtr := *(*[]uintptr)(unsafe.Pointer(&dst)) srcPtr := *(*[]uintptr)(unsafe.Pointer(&src)) withPtr := *(*[]uintptr)(unsafe.Pointer(&with)) for i, v := range srcPtr[:w] { dstPtr[i] = withPtr[i] ^ v } } for i := (n & (^(wordSize - 1))); i < n; i++ { dst[i] = src[i] ^ with[i] } return n } golang-github-enceve-crypto-0.0~git20160707.34d48bb/xor_test.go000066400000000000000000000032711520706056300236700ustar00rootroot00000000000000package crypto import ( "bytes" "encoding/hex" "testing" "unsafe" ) func unalignBytes(in []byte) []byte { out := make([]byte, len(in)+1) if uintptr(unsafe.Pointer(&out[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { out = out[1:] } else { out = out[:len(in)] } copy(out, in) return out } func testXOR(t *testing.T, dSize, sSize, wSize int, unalign bool) { dst0, src, with := make([]byte, dSize), make([]byte, sSize), make([]byte, wSize) dst1 := make([]byte, dSize) if unalign { with = unalignBytes(with) } var n int if len(src) < len(with) { n = len(src) } else { n = len(with) } for i := 0; i < n; i++ { src[i] = byte(i) with[i] = byte(i + 1) dst0[i] = src[i] ^ with[i] } XOR(dst1, src, with) if !bytes.Equal(dst0, dst1) { t.Fatalf("xor failed:\nexpected: %s\ngot: %s", hex.EncodeToString(dst0), hex.EncodeToString(dst1)) } } func TestXOR(t *testing.T) { testXOR(t, 0, 0, 0, true) testXOR(t, 0, 0, 0, false) testXOR(t, 64, 64, 64, true) testXOR(t, 64, 64, 64, false) testXOR(t, 65, 64, 63, true) testXOR(t, 65, 64, 63, false) testXOR(t, 16, 16, 64, true) testXOR(t, 16, 16, 64, false) } func benchmarkXOR(b *testing.B, size int, unalign bool) { dst, src, with := make([]byte, size), make([]byte, size), make([]byte, size) if unalign { with = unalignBytes(with) } b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { XOR(dst, src, with) } } func BenchmarkXOR_64(b *testing.B) { benchmarkXOR(b, 64, false) } func BenchmarkXOR_1K(b *testing.B) { benchmarkXOR(b, 1024, false) } func BenchmarkXORUnaligned_64(b *testing.B) { benchmarkXOR(b, 64, true) } func BenchmarkXORUnaligned_1K(b *testing.B) { benchmarkXOR(b, 1024, true) }