├── ascon ├── asm │ ├── .gitignore │ ├── tools.go │ ├── go.mod │ ├── go.sum │ └── asm.go ├── internal │ ├── asconc │ │ ├── ref │ │ │ ├── ascon.h │ │ │ ├── api.h │ │ │ ├── printstate.h │ │ │ ├── printstate.c │ │ │ ├── crypto_aead.h │ │ │ ├── word.h │ │ │ ├── round.h │ │ │ ├── encrypt.c │ │ │ ├── decrypt.c │ │ │ ├── ref.go │ │ │ └── permutations.h │ │ └── refa │ │ │ ├── ascon.h │ │ │ ├── api.h │ │ │ ├── printstate.h │ │ │ ├── printstate.c │ │ │ ├── crypto_aead.h │ │ │ ├── word.h │ │ │ ├── round.h │ │ │ ├── ref.go │ │ │ ├── encrypt.c │ │ │ ├── decrypt.c │ │ │ └── permutations.h │ └── cmd │ │ └── pgen │ │ └── main.go ├── stub_arm64.go ├── stub_amd64.go ├── ascon_noasm.go ├── fuzz_test.go ├── ascon_test.go ├── ascon_arm64.s ├── ascon.go ├── zascon_generic.go └── ascon_amd64.s ├── grain ├── asm │ ├── .gitignore │ ├── tools.go │ ├── go.mod │ ├── go.sum │ └── asm.go ├── grain_noasm.go ├── stub_amd64.go ├── grain_test.go ├── grain_amd64.s └── grain.go ├── go.mod ├── .gitignore ├── .github └── workflows │ └── go.yml ├── LICENSE ├── README.md └── go.sum /ascon/asm/.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | make.bash 3 | -------------------------------------------------------------------------------- /grain/asm/.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | make.bash 3 | out.S 4 | out2.S 5 | -------------------------------------------------------------------------------- /ascon/internal/asconc/ref/ascon.h: -------------------------------------------------------------------------------- 1 | #ifndef ASCON_H_ 2 | #define ASCON_H_ 3 | 4 | #include 5 | 6 | typedef struct { 7 | uint64_t x0, x1, x2, x3, x4; 8 | } state_t; 9 | 10 | #endif /* ASCON_H */ 11 | -------------------------------------------------------------------------------- /ascon/internal/asconc/refa/ascon.h: -------------------------------------------------------------------------------- 1 | #ifndef ASCON_H_ 2 | #define ASCON_H_ 3 | 4 | #include 5 | 6 | typedef struct { 7 | uint64_t x0, x1, x2, x3, x4; 8 | } state_t; 9 | 10 | #endif /* ASCON_H */ 11 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ericlagergren/lwcrypto 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/ericlagergren/saferand v0.0.0-20211228043234-529f04ad6e1a 7 | github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010 8 | ) 9 | -------------------------------------------------------------------------------- /ascon/internal/asconc/ref/api.h: -------------------------------------------------------------------------------- 1 | #define CRYPTO_VERSION "1.2.5" 2 | #define CRYPTO_KEYBYTES 16 3 | #define CRYPTO_NSECBYTES 0 4 | #define CRYPTO_NPUBBYTES 16 5 | #define CRYPTO_ABYTES 16 6 | #define CRYPTO_NOOVERLAP 1 7 | #define ASCON_AEAD_RATE 8 8 | -------------------------------------------------------------------------------- /ascon/internal/asconc/refa/api.h: -------------------------------------------------------------------------------- 1 | #define CRYPTO_VERSION "1.2.5" 2 | #define CRYPTO_KEYBYTES 16 3 | #define CRYPTO_NSECBYTES 0 4 | #define CRYPTO_NPUBBYTES 16 5 | #define CRYPTO_ABYTES 16 6 | #define CRYPTO_NOOVERLAP 1 7 | #define ASCON_AEAD_RATE 16 8 | -------------------------------------------------------------------------------- /ascon/asm/tools.go: -------------------------------------------------------------------------------- 1 | // +build tools 2 | 3 | package lwcrypto 4 | 5 | import ( 6 | _ "github.com/mmcloughlin/avo/build" 7 | _ "github.com/mmcloughlin/avo/gotypes" 8 | _ "github.com/mmcloughlin/avo/operand" 9 | _ "github.com/mmcloughlin/avo/reg" 10 | ) 11 | -------------------------------------------------------------------------------- /grain/asm/tools.go: -------------------------------------------------------------------------------- 1 | // +build tools 2 | 3 | package lwcrypto 4 | 5 | import ( 6 | _ "github.com/mmcloughlin/avo/build" 7 | _ "github.com/mmcloughlin/avo/gotypes" 8 | _ "github.com/mmcloughlin/avo/operand" 9 | _ "github.com/mmcloughlin/avo/reg" 10 | ) 11 | -------------------------------------------------------------------------------- /grain/grain_noasm.go: -------------------------------------------------------------------------------- 1 | // +build !amd64 !gc purego 2 | 3 | package grain 4 | 5 | func next(s *state) uint32 { 6 | return nextGeneric(s) 7 | } 8 | 9 | func accumulate(reg, acc uint64, ms, pt uint16) (uint64, uint64) { 10 | return accumulateGeneric(reg, acc, ms, pt) 11 | } 12 | -------------------------------------------------------------------------------- /ascon/asm/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ericlagergren/lwcrypto/ascon/asm 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/ericlagergren/lwcrypto v0.0.0-00010101000000-000000000000 7 | github.com/mmcloughlin/avo v0.2.0 8 | ) 9 | 10 | replace github.com/ericlagergren/lwcrypto => ../../ 11 | -------------------------------------------------------------------------------- /grain/asm/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ericlagergren/lwcrypto/grain/asm 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/ericlagergren/lwcrypto v0.0.0-00010101000000-000000000000 7 | github.com/mmcloughlin/avo v0.2.0 8 | golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 // indirect 9 | ) 10 | 11 | replace github.com/ericlagergren/lwcrypto => ../../ 12 | -------------------------------------------------------------------------------- /grain/stub_amd64.go: -------------------------------------------------------------------------------- 1 | // Code generated by command: go run asm.go -out out/grain_amd64.s -stubs out/stub_amd64.go -pkg grain. DO NOT EDIT. 2 | 3 | // +build gc,!purego 4 | 5 | package grain 6 | 7 | //go:noescape 8 | func next(s *state) uint32 9 | 10 | //go:noescape 11 | func accumulate(reg uint64, acc uint64, ms uint16, pt uint16) (reg1 uint64, acc1 uint64) 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | 17 | elephant/ 18 | 19 | *.txt 20 | 21 | ascon_simd_arm64.s 22 | -------------------------------------------------------------------------------- /ascon/stub_arm64.go: -------------------------------------------------------------------------------- 1 | //go:build gc && !purego 2 | // +build gc,!purego 3 | 4 | package ascon 5 | 6 | //go:noescape 7 | func p12(s *state) 8 | 9 | //go:noescape 10 | func p8(s *state) 11 | 12 | //go:noescape 13 | func p6(s *state) 14 | 15 | //go:noescape 16 | func round(s *state, C uint64) 17 | 18 | //go:noescape 19 | func additionalData128a(s *state, ad []byte) 20 | 21 | //go:noescape 22 | func encryptBlocks128a(s *state, dst, src []byte) 23 | 24 | //go:noescape 25 | func decryptBlocks128a(s *state, dst, src []byte) 26 | -------------------------------------------------------------------------------- /ascon/internal/asconc/ref/printstate.h: -------------------------------------------------------------------------------- 1 | #ifndef PRINTSTATE_H_ 2 | #define PRINTSTATE_H_ 3 | 4 | #ifdef ASCON_PRINTSTATE 5 | 6 | #include "ascon.h" 7 | #include "word.h" 8 | 9 | void printword(const char* text, const word_t x); 10 | void printstate(const char* text, const state_t* s); 11 | 12 | #else 13 | 14 | #define printword(text, w) \ 15 | do { \ 16 | } while (0) 17 | 18 | #define printstate(text, s) \ 19 | do { \ 20 | } while (0) 21 | 22 | #endif 23 | 24 | #endif /* PRINTSTATE_H_ */ 25 | -------------------------------------------------------------------------------- /ascon/internal/asconc/refa/printstate.h: -------------------------------------------------------------------------------- 1 | #ifndef PRINTSTATE_H_ 2 | #define PRINTSTATE_H_ 3 | 4 | #ifdef ASCON_PRINTSTATE 5 | 6 | #include "ascon.h" 7 | #include "word.h" 8 | 9 | void printword(const char* text, const word_t x); 10 | void printstate(const char* text, const state_t* s); 11 | 12 | #else 13 | 14 | #define printword(text, w) \ 15 | do { \ 16 | } while (0) 17 | 18 | #define printstate(text, s) \ 19 | do { \ 20 | } while (0) 21 | 22 | #endif 23 | 24 | #endif /* PRINTSTATE_H_ */ 25 | -------------------------------------------------------------------------------- /ascon/internal/asconc/ref/printstate.c: -------------------------------------------------------------------------------- 1 | #ifdef ASCON_PRINTSTATE 2 | 3 | #include "printstate.h" 4 | 5 | #include 6 | #include 7 | 8 | void printword(const char* text, const word_t x) { 9 | printf("%s=%016" PRIx64 "\n", text, WORDTOU64(x)); 10 | } 11 | 12 | void printstate(const char* text, const state_t* s) { 13 | printf("%s:\n", text); 14 | printword(" x0", s->x0); 15 | printword(" x1", s->x1); 16 | printword(" x2", s->x2); 17 | printword(" x3", s->x3); 18 | printword(" x4", s->x4); 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /ascon/internal/asconc/refa/printstate.c: -------------------------------------------------------------------------------- 1 | #ifdef ASCON_PRINTSTATE 2 | 3 | #include "printstate.h" 4 | 5 | #include 6 | #include 7 | 8 | void printword(const char* text, const word_t x) { 9 | printf("%s=%016" PRIx64 "\n", text, WORDTOU64(x)); 10 | } 11 | 12 | void printstate(const char* text, const state_t* s) { 13 | printf("%s:\n", text); 14 | printword(" x0", s->x0); 15 | printword(" x1", s->x1); 16 | printword(" x2", s->x2); 17 | printword(" x3", s->x3); 18 | printword(" x4", s->x4); 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /ascon/internal/asconc/ref/crypto_aead.h: -------------------------------------------------------------------------------- 1 | int crypto_aead_encrypt(unsigned char *c, unsigned long long *clen, 2 | const unsigned char *m, unsigned long long mlen, 3 | const unsigned char *ad, unsigned long long adlen, 4 | const unsigned char *nsec, const unsigned char *npub, 5 | const unsigned char *k); 6 | 7 | int crypto_aead_decrypt(unsigned char *m, unsigned long long *mlen, 8 | unsigned char *nsec, const unsigned char *c, 9 | unsigned long long clen, const unsigned char *ad, 10 | unsigned long long adlen, const unsigned char *npub, 11 | const unsigned char *k); 12 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Set up Go 17 | uses: actions/setup-go@v2 18 | with: 19 | go-version: 1.17 20 | 21 | - name: Build 22 | run: go build -v ./... 23 | 24 | - name: Test 25 | run: go test -v -vet all -tags fuzz ./... 26 | 27 | - name: TestPureGo 28 | run: go test -v -vet all -tags fuzz,purego ./... 29 | -------------------------------------------------------------------------------- /ascon/internal/asconc/refa/crypto_aead.h: -------------------------------------------------------------------------------- 1 | int crypto_aead_encrypt_a(unsigned char *c, unsigned long long *clen, 2 | const unsigned char *m, unsigned long long mlen, 3 | const unsigned char *ad, unsigned long long adlen, 4 | const unsigned char *nsec, const unsigned char *npub, 5 | const unsigned char *k); 6 | 7 | int crypto_aead_decrypt_a(unsigned char *m, unsigned long long *mlen, 8 | unsigned char *nsec, const unsigned char *c, 9 | unsigned long long clen, const unsigned char *ad, 10 | unsigned long long adlen, const unsigned char *npub, 11 | const unsigned char *k); 12 | -------------------------------------------------------------------------------- /ascon/stub_amd64.go: -------------------------------------------------------------------------------- 1 | // Code generated by command: go run asm.go -out out/ascon_amd64.s -stubs out/stub_amd64.go -pkg ascon. DO NOT EDIT. 2 | 3 | //go:build gc && !purego 4 | // +build gc,!purego 5 | 6 | package ascon 7 | 8 | //go:noescape 9 | func p12(s *state) 10 | 11 | //go:noescape 12 | func p8(s *state) 13 | 14 | //go:noescape 15 | func p6(s *state) 16 | 17 | //go:noescape 18 | func round(s *state, C uint64) 19 | 20 | //go:noescape 21 | func additionalData128a(s *state, ad []byte) 22 | 23 | //go:noescape 24 | func encryptBlocks128a(s *state, dst []byte, src []byte) 25 | 26 | //go:noescape 27 | func decryptBlocks128a(s *state, dst []byte, src []byte) 28 | -------------------------------------------------------------------------------- /ascon/ascon_noasm.go: -------------------------------------------------------------------------------- 1 | //go:build !(amd64 || arm64 || gc) || purego 2 | // +build !amd64,!arm64,!gc purego 3 | 4 | package ascon 5 | 6 | func additionalData128a(s *state, ad []byte) { 7 | additionalData128aGeneric(s, ad) 8 | } 9 | 10 | func encryptBlocks128a(s *state, dst, src []byte) { 11 | encryptBlocks128aGeneric(s, dst, src) 12 | } 13 | 14 | func decryptBlocks128a(s *state, dst, src []byte) { 15 | decryptBlocks128aGeneric(s, dst, src) 16 | } 17 | 18 | func round(s *state, C uint64) { 19 | roundGeneric(s, C) 20 | } 21 | 22 | func p12(s *state) { 23 | p12Generic(s) 24 | } 25 | 26 | func p8(s *state) { 27 | p8Generic(s) 28 | } 29 | 30 | func p6(s *state) { 31 | p6Generic(s) 32 | } 33 | -------------------------------------------------------------------------------- /ascon/internal/asconc/ref/word.h: -------------------------------------------------------------------------------- 1 | #ifndef WORD_H_ 2 | #define WORD_H_ 3 | 4 | #include 5 | 6 | #define WORDTOU64 7 | #define U64TOWORD 8 | 9 | typedef uint64_t word_t; 10 | 11 | /* get byte from 64-bit Ascon word */ 12 | #define GETBYTE(x, i) ((uint8_t)((uint64_t)(x) >> (56 - 8 * (i)))) 13 | 14 | /* set byte in 64-bit Ascon word */ 15 | #define SETBYTE(b, i) ((uint64_t)(b) << (56 - 8 * (i))) 16 | 17 | /* set padding byte in 64-bit Ascon word */ 18 | #define PAD(i) SETBYTE(0x80, i) 19 | 20 | /* load bytes into 64-bit Ascon word */ 21 | static inline uint64_t LOADBYTES(const uint8_t* bytes, int n) { 22 | uint64_t x = 0; 23 | for (int i = 0; i < n; ++i) x |= SETBYTE(bytes[i], i); 24 | return x; 25 | } 26 | 27 | /* store bytes from 64-bit Ascon word */ 28 | static inline void STOREBYTES(uint8_t* bytes, uint64_t x, int n) { 29 | for (int i = 0; i < n; ++i) bytes[i] = GETBYTE(x, i); 30 | } 31 | 32 | /* clear bytes in 64-bit Ascon word */ 33 | static inline uint64_t CLEARBYTES(uint64_t x, int n) { 34 | for (int i = 0; i < n; ++i) x &= ~SETBYTE(0xff, i); 35 | return x; 36 | } 37 | 38 | #endif /* WORD_H_ */ 39 | -------------------------------------------------------------------------------- /ascon/internal/asconc/refa/word.h: -------------------------------------------------------------------------------- 1 | #ifndef WORD_H_ 2 | #define WORD_H_ 3 | 4 | #include 5 | 6 | #define WORDTOU64 7 | #define U64TOWORD 8 | 9 | typedef uint64_t word_t; 10 | 11 | /* get byte from 64-bit Ascon word */ 12 | #define GETBYTE(x, i) ((uint8_t)((uint64_t)(x) >> (56 - 8 * (i)))) 13 | 14 | /* set byte in 64-bit Ascon word */ 15 | #define SETBYTE(b, i) ((uint64_t)(b) << (56 - 8 * (i))) 16 | 17 | /* set padding byte in 64-bit Ascon word */ 18 | #define PAD(i) SETBYTE(0x80, i) 19 | 20 | /* load bytes into 64-bit Ascon word */ 21 | static inline uint64_t LOADBYTES(const uint8_t* bytes, int n) { 22 | uint64_t x = 0; 23 | for (int i = 0; i < n; ++i) x |= SETBYTE(bytes[i], i); 24 | return x; 25 | } 26 | 27 | /* store bytes from 64-bit Ascon word */ 28 | static inline void STOREBYTES(uint8_t* bytes, uint64_t x, int n) { 29 | for (int i = 0; i < n; ++i) bytes[i] = GETBYTE(x, i); 30 | } 31 | 32 | /* clear bytes in 64-bit Ascon word */ 33 | static inline uint64_t CLEARBYTES(uint64_t x, int n) { 34 | for (int i = 0; i < n; ++i) x &= ~SETBYTE(0xff, i); 35 | return x; 36 | } 37 | 38 | #endif /* WORD_H_ */ 39 | -------------------------------------------------------------------------------- /ascon/internal/asconc/ref/round.h: -------------------------------------------------------------------------------- 1 | #ifndef ROUND_H_ 2 | #define ROUND_H_ 3 | 4 | #include "ascon.h" 5 | #include "printstate.h" 6 | 7 | static inline uint64_t ROR(uint64_t x, int n) { 8 | return (x << (64 - n)) | (x >> n); 9 | } 10 | 11 | static inline void ROUND(state_t* s, uint8_t C) { 12 | state_t t; 13 | /* addition of round constant */ 14 | s->x2 ^= C; 15 | /* printstate(" round constant", s); */ 16 | /* substitution layer */ 17 | s->x0 ^= s->x4; 18 | s->x4 ^= s->x3; 19 | s->x2 ^= s->x1; 20 | /* start of keccak s-box */ 21 | t.x0 = s->x0 ^ (~s->x1 & s->x2); 22 | t.x1 = s->x1 ^ (~s->x2 & s->x3); 23 | t.x2 = s->x2 ^ (~s->x3 & s->x4); 24 | t.x3 = s->x3 ^ (~s->x4 & s->x0); 25 | t.x4 = s->x4 ^ (~s->x0 & s->x1); 26 | /* end of keccak s-box */ 27 | t.x1 ^= t.x0; 28 | t.x0 ^= t.x4; 29 | t.x3 ^= t.x2; 30 | t.x2 = ~t.x2; 31 | /* printstate(" substitution layer", &t); */ 32 | /* linear diffusion layer */ 33 | s->x0 = t.x0 ^ ROR(t.x0, 19) ^ ROR(t.x0, 28); 34 | s->x1 = t.x1 ^ ROR(t.x1, 61) ^ ROR(t.x1, 39); 35 | s->x2 = t.x2 ^ ROR(t.x2, 1) ^ ROR(t.x2, 6); 36 | s->x3 = t.x3 ^ ROR(t.x3, 10) ^ ROR(t.x3, 17); 37 | s->x4 = t.x4 ^ ROR(t.x4, 7) ^ ROR(t.x4, 41); 38 | printstate(" round output", s); 39 | } 40 | 41 | #endif /* ROUND_H_ */ 42 | -------------------------------------------------------------------------------- /ascon/internal/asconc/refa/round.h: -------------------------------------------------------------------------------- 1 | #ifndef ROUND_H_ 2 | #define ROUND_H_ 3 | 4 | #include "ascon.h" 5 | #include "printstate.h" 6 | 7 | static inline uint64_t ROR(uint64_t x, int n) { 8 | return (x << (64 - n)) | (x >> n); 9 | } 10 | 11 | static inline void ROUND(state_t* s, uint8_t C) { 12 | state_t t; 13 | /* addition of round constant */ 14 | s->x2 ^= C; 15 | /* printstate(" round constant", s); */ 16 | /* substitution layer */ 17 | s->x0 ^= s->x4; 18 | s->x4 ^= s->x3; 19 | s->x2 ^= s->x1; 20 | /* start of keccak s-box */ 21 | t.x0 = s->x0 ^ (~s->x1 & s->x2); 22 | t.x1 = s->x1 ^ (~s->x2 & s->x3); 23 | t.x2 = s->x2 ^ (~s->x3 & s->x4); 24 | t.x3 = s->x3 ^ (~s->x4 & s->x0); 25 | t.x4 = s->x4 ^ (~s->x0 & s->x1); 26 | /* end of keccak s-box */ 27 | t.x1 ^= t.x0; 28 | t.x0 ^= t.x4; 29 | t.x3 ^= t.x2; 30 | t.x2 = ~t.x2; 31 | /* printstate(" substitution layer", &t); */ 32 | /* linear diffusion layer */ 33 | s->x0 = t.x0 ^ ROR(t.x0, 19) ^ ROR(t.x0, 28); 34 | s->x1 = t.x1 ^ ROR(t.x1, 61) ^ ROR(t.x1, 39); 35 | s->x2 = t.x2 ^ ROR(t.x2, 1) ^ ROR(t.x2, 6); 36 | s->x3 = t.x3 ^ ROR(t.x3, 10) ^ ROR(t.x3, 17); 37 | s->x4 = t.x4 ^ ROR(t.x4, 7) ^ ROR(t.x4, 41); 38 | printstate(" round output", s); 39 | } 40 | 41 | #endif /* ROUND_H_ */ 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, Eric Lagergren 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /ascon/internal/asconc/ref/encrypt.c: -------------------------------------------------------------------------------- 1 | #include "api.h" 2 | #include "ascon.h" 3 | #include "crypto_aead.h" 4 | #include "permutations.h" 5 | #include "printstate.h" 6 | #include "word.h" 7 | 8 | int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen, 9 | const unsigned char* m, unsigned long long mlen, 10 | const unsigned char* ad, unsigned long long adlen, 11 | const unsigned char* nsec, const unsigned char* npub, 12 | const unsigned char* k) { 13 | (void)nsec; 14 | 15 | /* set ciphertext size */ 16 | *clen = mlen + CRYPTO_ABYTES; 17 | 18 | /* load key and nonce */ 19 | const uint64_t K0 = LOADBYTES(k, 8); 20 | const uint64_t K1 = LOADBYTES(k + 8, 8); 21 | const uint64_t N0 = LOADBYTES(npub, 8); 22 | const uint64_t N1 = LOADBYTES(npub + 8, 8); 23 | 24 | /* initialize */ 25 | state_t s; 26 | s.x0 = ASCON_128_IV; 27 | s.x1 = K0; 28 | s.x2 = K1; 29 | s.x3 = N0; 30 | s.x4 = N1; 31 | P12(&s); 32 | s.x3 ^= K0; 33 | s.x4 ^= K1; 34 | printstate("initialization", &s); 35 | 36 | if (adlen) { 37 | /* full associated data blocks */ 38 | while (adlen >= ASCON_128_RATE) { 39 | s.x0 ^= LOADBYTES(ad, 8); 40 | P6(&s); 41 | ad += ASCON_128_RATE; 42 | adlen -= ASCON_128_RATE; 43 | } 44 | /* final associated data block */ 45 | s.x0 ^= LOADBYTES(ad, adlen); 46 | s.x0 ^= PAD(adlen); 47 | P6(&s); 48 | } 49 | /* domain separation */ 50 | s.x4 ^= 1; 51 | printstate("process associated data", &s); 52 | 53 | /* full plaintext blocks */ 54 | while (mlen >= ASCON_128_RATE) { 55 | s.x0 ^= LOADBYTES(m, 8); 56 | STOREBYTES(c, s.x0, 8); 57 | P6(&s); 58 | m += ASCON_128_RATE; 59 | c += ASCON_128_RATE; 60 | mlen -= ASCON_128_RATE; 61 | } 62 | /* final plaintext block */ 63 | s.x0 ^= LOADBYTES(m, mlen); 64 | STOREBYTES(c, s.x0, mlen); 65 | s.x0 ^= PAD(mlen); 66 | c += mlen; 67 | printstate("process plaintext", &s); 68 | 69 | /* finalize */ 70 | s.x1 ^= K0; 71 | s.x2 ^= K1; 72 | P12(&s); 73 | s.x3 ^= K0; 74 | s.x4 ^= K1; 75 | printstate("finalization", &s); 76 | 77 | /* set tag */ 78 | STOREBYTES(c, s.x3, 8); 79 | STOREBYTES(c + 8, s.x4, 8); 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /ascon/fuzz_test.go: -------------------------------------------------------------------------------- 1 | //go:build fuzz 2 | 3 | package ascon_test 4 | 5 | import ( 6 | "bytes" 7 | "crypto/cipher" 8 | "os" 9 | "testing" 10 | "time" 11 | 12 | "github.com/ericlagergren/lwcrypto/ascon" 13 | ref "github.com/ericlagergren/lwcrypto/ascon/internal/asconc/ref" 14 | refa "github.com/ericlagergren/lwcrypto/ascon/internal/asconc/refa" 15 | rand "github.com/ericlagergren/saferand" 16 | ) 17 | 18 | func TestFuzz(t *testing.T) { 19 | t.Run("128", func(t *testing.T) { 20 | t.Parallel() 21 | 22 | testFuzz(t, ref.New, ascon.New128) 23 | }) 24 | t.Run("128a", func(t *testing.T) { 25 | t.Parallel() 26 | 27 | testFuzz(t, refa.New, ascon.New128a) 28 | }) 29 | } 30 | 31 | func testFuzz(t *testing.T, ref, test func([]byte) (cipher.AEAD, error)) { 32 | d := 2 * time.Second 33 | if testing.Short() { 34 | d = 10 * time.Millisecond 35 | } 36 | if s := os.Getenv("ASCON_FUZZ_TIMEOUT"); s != "" { 37 | var err error 38 | d, err = time.ParseDuration(s) 39 | if err != nil { 40 | t.Fatal(err) 41 | } 42 | } 43 | tm := time.NewTimer(d) 44 | 45 | key := make([]byte, ascon.KeySize) 46 | nonce := make([]byte, ascon.NonceSize) 47 | plaintext := make([]byte, 1*1024*1024) // 1 MB 48 | for i := 0; ; i++ { 49 | select { 50 | case <-tm.C: 51 | t.Logf("iters: %d", i) 52 | return 53 | default: 54 | } 55 | 56 | if _, err := rand.Read(key); err != nil { 57 | t.Fatal(err) 58 | } 59 | if _, err := rand.Read(nonce); err != nil { 60 | t.Fatal(err) 61 | } 62 | n := rand.Intn(len(plaintext)) 63 | if _, err := rand.Read(plaintext[:n]); err != nil { 64 | t.Fatal(err) 65 | } 66 | plaintext := plaintext[:n] 67 | 68 | refAead, err := ref(key) 69 | if err != nil { 70 | t.Fatal(err) 71 | } 72 | gotAead, err := test(key) 73 | if err != nil { 74 | t.Fatal(err) 75 | } 76 | 77 | wantCt := refAead.Seal(nil, nonce, plaintext, nil) 78 | gotCt := gotAead.Seal(nil, nonce, plaintext, nil) 79 | if !bytes.Equal(wantCt, gotCt) { 80 | t.Fatalf("expected %#x, got %#x", wantCt, gotCt) 81 | } 82 | 83 | wantPt, err := refAead.Open(nil, nonce, wantCt, nil) 84 | if err != nil { 85 | t.Fatal(err) 86 | } 87 | gotPt, err := gotAead.Open(nil, nonce, wantCt, nil) 88 | if err != nil { 89 | t.Fatal(err) 90 | } 91 | if !bytes.Equal(wantPt, gotPt) { 92 | t.Fatalf("expected %#x, got %#x", wantPt, gotPt) 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /ascon/internal/asconc/ref/decrypt.c: -------------------------------------------------------------------------------- 1 | #include "api.h" 2 | #include "ascon.h" 3 | #include "crypto_aead.h" 4 | #include "permutations.h" 5 | #include "printstate.h" 6 | #include "word.h" 7 | 8 | int crypto_aead_decrypt(unsigned char* m, unsigned long long* mlen, 9 | unsigned char* nsec, const unsigned char* c, 10 | unsigned long long clen, const unsigned char* ad, 11 | unsigned long long adlen, const unsigned char* npub, 12 | const unsigned char* k) { 13 | (void)nsec; 14 | 15 | if (clen < CRYPTO_ABYTES) return -1; 16 | 17 | /* set plaintext size */ 18 | *mlen = clen - CRYPTO_ABYTES; 19 | 20 | /* load key and nonce */ 21 | const uint64_t K0 = LOADBYTES(k, 8); 22 | const uint64_t K1 = LOADBYTES(k + 8, 8); 23 | const uint64_t N0 = LOADBYTES(npub, 8); 24 | const uint64_t N1 = LOADBYTES(npub + 8, 8); 25 | 26 | /* initialize */ 27 | state_t s; 28 | s.x0 = ASCON_128_IV; 29 | s.x1 = K0; 30 | s.x2 = K1; 31 | s.x3 = N0; 32 | s.x4 = N1; 33 | P12(&s); 34 | s.x3 ^= K0; 35 | s.x4 ^= K1; 36 | printstate("initialization", &s); 37 | 38 | if (adlen) { 39 | /* full associated data blocks */ 40 | while (adlen >= ASCON_128_RATE) { 41 | s.x0 ^= LOADBYTES(ad, 8); 42 | P6(&s); 43 | ad += ASCON_128_RATE; 44 | adlen -= ASCON_128_RATE; 45 | } 46 | /* final associated data block */ 47 | s.x0 ^= LOADBYTES(ad, adlen); 48 | s.x0 ^= PAD(adlen); 49 | P6(&s); 50 | } 51 | /* domain separation */ 52 | s.x4 ^= 1; 53 | printstate("process associated data", &s); 54 | 55 | /* full ciphertext blocks */ 56 | clen -= CRYPTO_ABYTES; 57 | while (clen >= ASCON_128_RATE) { 58 | uint64_t c0 = LOADBYTES(c, 8); 59 | STOREBYTES(m, s.x0 ^ c0, 8); 60 | s.x0 = c0; 61 | P6(&s); 62 | m += ASCON_128_RATE; 63 | c += ASCON_128_RATE; 64 | clen -= ASCON_128_RATE; 65 | } 66 | /* final ciphertext block */ 67 | uint64_t c0 = LOADBYTES(c, clen); 68 | STOREBYTES(m, s.x0 ^ c0, clen); 69 | s.x0 = CLEARBYTES(s.x0, clen); 70 | s.x0 |= c0; 71 | s.x0 ^= PAD(clen); 72 | c += clen; 73 | printstate("process ciphertext", &s); 74 | 75 | /* finalize */ 76 | s.x1 ^= K0; 77 | s.x2 ^= K1; 78 | P12(&s); 79 | s.x3 ^= K0; 80 | s.x4 ^= K1; 81 | printstate("finalization", &s); 82 | 83 | /* set tag */ 84 | uint8_t t[16]; 85 | STOREBYTES(t, s.x3, 8); 86 | STOREBYTES(t + 8, s.x4, 8); 87 | 88 | /* verify tag (should be constant time, check compiler output) */ 89 | int result = 0; 90 | for (int i = 0; i < CRYPTO_ABYTES; ++i) result |= c[i] ^ t[i]; 91 | result = (((result - 1) >> 8) & 1) - 1; 92 | 93 | return result; 94 | } 95 | -------------------------------------------------------------------------------- /ascon/internal/asconc/ref/ref.go: -------------------------------------------------------------------------------- 1 | // Package ref implements a wrapper around the reference 2 | // implementation of ASCON. 3 | // 4 | // Version used: https://github.com/ascon/ascon-c/tree/a664d3bb2dfa092d550025c440730c56c198e326/crypto_aead/ascon128v12/ref 5 | package ref 6 | 7 | /* 8 | #include "ascon.h" 9 | #include "api.h" 10 | #include "crypto_aead.h" 11 | */ 12 | import "C" 13 | 14 | import ( 15 | "crypto/cipher" 16 | "errors" 17 | "fmt" 18 | 19 | "github.com/ericlagergren/subtle" 20 | ) 21 | 22 | type aead struct { 23 | key []byte 24 | } 25 | 26 | func New(key []byte) (cipher.AEAD, error) { 27 | switch len(key) { 28 | case C.CRYPTO_KEYBYTES: 29 | return &aead{key: key}, nil 30 | default: 31 | return nil, fmt.Errorf("invalid key size: %d", len(key)) 32 | } 33 | } 34 | 35 | func (a *aead) NonceSize() int { 36 | return C.CRYPTO_NPUBBYTES 37 | } 38 | 39 | func (a *aead) Overhead() int { 40 | return C.CRYPTO_ABYTES 41 | } 42 | 43 | func (a *aead) Seal(dst, nonce, plaintext, additionalData []byte) []byte { 44 | ret, out := subtle.SliceForAppend(dst, len(plaintext)+C.CRYPTO_ABYTES) 45 | if subtle.InexactOverlap(out, plaintext) { 46 | panic("ascon: invalid buffer overlap") 47 | } 48 | var m *C.uchar 49 | if len(plaintext) > 0 { 50 | m = (*C.uchar)(&plaintext[0]) 51 | } 52 | var ad *C.uchar 53 | if len(additionalData) > 0 { 54 | ad = (*C.uchar)(&additionalData[0]) 55 | } 56 | clen := C.ulonglong(len(out)) 57 | r := C.crypto_aead_encrypt( 58 | (*C.uchar)(&out[0]), 59 | &clen, 60 | m, 61 | C.ulonglong(len(plaintext)), 62 | ad, 63 | C.ulonglong(len(additionalData)), 64 | nil, 65 | (*C.uchar)(&nonce[0]), 66 | (*C.uchar)(&a.key[0]), 67 | ) 68 | if r != 0 { 69 | panic("crypto_aead_encrypt") 70 | } 71 | return ret 72 | } 73 | 74 | func (a *aead) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { 75 | ret, out := subtle.SliceForAppend(dst, len(ciphertext)-C.CRYPTO_ABYTES) 76 | if subtle.InexactOverlap(out, ciphertext) { 77 | panic("ascon: invalid buffer overlap") 78 | } 79 | if len(ciphertext) < C.CRYPTO_ABYTES { 80 | return nil, errors.New("ciphertext too short") 81 | } 82 | var ad *C.uchar 83 | if len(additionalData) > 0 { 84 | ad = (*C.uchar)(&additionalData[0]) 85 | } 86 | mlen := C.ulonglong(len(out)) 87 | r := C.crypto_aead_decrypt( 88 | (*C.uchar)(&out[0]), 89 | &mlen, 90 | nil, 91 | (*C.uchar)(&ciphertext[0]), 92 | C.ulonglong(len(ciphertext)), 93 | ad, 94 | C.ulonglong(len(additionalData)), 95 | (*C.uchar)(&nonce[0]), 96 | (*C.uchar)(&a.key[0]), 97 | ) 98 | if r != 0 { 99 | for i := range out { 100 | out[i] = 0 101 | } 102 | return nil, errors.New("auth failed") 103 | } 104 | return ret, nil 105 | } 106 | -------------------------------------------------------------------------------- /ascon/internal/asconc/refa/ref.go: -------------------------------------------------------------------------------- 1 | // Package ref implements a wrapper around the reference 2 | // implementation of ASCON. 3 | // 4 | // Version used: https://github.com/ascon/ascon-c/tree/a664d3bb2dfa092d550025c440730c56c198e326/crypto_aead/ascon128av12 5 | package ref 6 | 7 | /* 8 | #include "ascon.h" 9 | #include "api.h" 10 | #include "crypto_aead.h" 11 | */ 12 | import "C" 13 | 14 | import ( 15 | "crypto/cipher" 16 | "errors" 17 | "fmt" 18 | 19 | "github.com/ericlagergren/subtle" 20 | ) 21 | 22 | type aead struct { 23 | key []byte 24 | } 25 | 26 | func New(key []byte) (cipher.AEAD, error) { 27 | switch len(key) { 28 | case C.CRYPTO_KEYBYTES: 29 | return &aead{key: key}, nil 30 | default: 31 | return nil, fmt.Errorf("invalid key size: %d", len(key)) 32 | } 33 | } 34 | 35 | func (a *aead) NonceSize() int { 36 | return C.CRYPTO_NPUBBYTES 37 | } 38 | 39 | func (a *aead) Overhead() int { 40 | return C.CRYPTO_ABYTES 41 | } 42 | 43 | func (a *aead) Seal(dst, nonce, plaintext, additionalData []byte) []byte { 44 | ret, out := subtle.SliceForAppend(dst, len(plaintext)+C.CRYPTO_ABYTES) 45 | if subtle.InexactOverlap(out, plaintext) { 46 | panic("ascon: invalid buffer overlap") 47 | } 48 | var m *C.uchar 49 | if len(plaintext) > 0 { 50 | m = (*C.uchar)(&plaintext[0]) 51 | } 52 | var ad *C.uchar 53 | if len(additionalData) > 0 { 54 | ad = (*C.uchar)(&additionalData[0]) 55 | } 56 | clen := C.ulonglong(len(out)) 57 | r := C.crypto_aead_encrypt_a( 58 | (*C.uchar)(&out[0]), 59 | &clen, 60 | m, 61 | C.ulonglong(len(plaintext)), 62 | ad, 63 | C.ulonglong(len(additionalData)), 64 | nil, 65 | (*C.uchar)(&nonce[0]), 66 | (*C.uchar)(&a.key[0]), 67 | ) 68 | if r != 0 { 69 | panic("crypto_aead_encrypt") 70 | } 71 | return ret 72 | } 73 | 74 | func (a *aead) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { 75 | ret, out := subtle.SliceForAppend(dst, len(ciphertext)-C.CRYPTO_ABYTES) 76 | if subtle.InexactOverlap(out, ciphertext) { 77 | panic("ascon: invalid buffer overlap") 78 | } 79 | if len(ciphertext) < C.CRYPTO_ABYTES { 80 | return nil, errors.New("ciphertext too short") 81 | } 82 | var ad *C.uchar 83 | if len(additionalData) > 0 { 84 | ad = (*C.uchar)(&additionalData[0]) 85 | } 86 | mlen := C.ulonglong(len(out)) 87 | r := C.crypto_aead_decrypt_a( 88 | (*C.uchar)(&out[0]), 89 | &mlen, 90 | nil, 91 | (*C.uchar)(&ciphertext[0]), 92 | C.ulonglong(len(ciphertext)), 93 | ad, 94 | C.ulonglong(len(additionalData)), 95 | (*C.uchar)(&nonce[0]), 96 | (*C.uchar)(&a.key[0]), 97 | ) 98 | if r != 0 { 99 | for i := range out { 100 | out[i] = 0 101 | } 102 | return nil, errors.New("auth failed") 103 | } 104 | return ret, nil 105 | } 106 | -------------------------------------------------------------------------------- /ascon/internal/asconc/refa/encrypt.c: -------------------------------------------------------------------------------- 1 | #include "api.h" 2 | #include "ascon.h" 3 | #include "crypto_aead.h" 4 | #include "permutations.h" 5 | #include "printstate.h" 6 | #include "word.h" 7 | 8 | int crypto_aead_encrypt_a(unsigned char* c, unsigned long long* clen, 9 | const unsigned char* m, unsigned long long mlen, 10 | const unsigned char* ad, unsigned long long adlen, 11 | const unsigned char* nsec, const unsigned char* npub, 12 | const unsigned char* k) { 13 | (void)nsec; 14 | 15 | /* set ciphertext size */ 16 | *clen = mlen + CRYPTO_ABYTES; 17 | 18 | /* load key and nonce */ 19 | const uint64_t K0 = LOADBYTES(k, 8); 20 | const uint64_t K1 = LOADBYTES(k + 8, 8); 21 | const uint64_t N0 = LOADBYTES(npub, 8); 22 | const uint64_t N1 = LOADBYTES(npub + 8, 8); 23 | 24 | /* initialize */ 25 | state_t s; 26 | s.x0 = ASCON_128A_IV; 27 | s.x1 = K0; 28 | s.x2 = K1; 29 | s.x3 = N0; 30 | s.x4 = N1; 31 | P12(&s); 32 | s.x3 ^= K0; 33 | s.x4 ^= K1; 34 | printstate("initialization", &s); 35 | 36 | if (adlen) { 37 | /* full associated data blocks */ 38 | while (adlen >= ASCON_128A_RATE) { 39 | s.x0 ^= LOADBYTES(ad, 8); 40 | s.x1 ^= LOADBYTES(ad + 8, 8); 41 | P8(&s); 42 | ad += ASCON_128A_RATE; 43 | adlen -= ASCON_128A_RATE; 44 | } 45 | /* final associated data block */ 46 | if (adlen >= 8) { 47 | s.x0 ^= LOADBYTES(ad, 8); 48 | s.x1 ^= LOADBYTES(ad + 8, adlen - 8); 49 | s.x1 ^= PAD(adlen - 8); 50 | } else { 51 | s.x0 ^= LOADBYTES(ad, adlen); 52 | s.x0 ^= PAD(adlen); 53 | } 54 | P8(&s); 55 | } 56 | /* domain separation */ 57 | s.x4 ^= 1; 58 | printstate("process associated data", &s); 59 | 60 | /* full plaintext blocks */ 61 | while (mlen >= ASCON_128A_RATE) { 62 | s.x0 ^= LOADBYTES(m, 8); 63 | s.x1 ^= LOADBYTES(m + 8, 8); 64 | STOREBYTES(c, s.x0, 8); 65 | STOREBYTES(c + 8, s.x1, 8); 66 | P8(&s); 67 | m += ASCON_128A_RATE; 68 | c += ASCON_128A_RATE; 69 | mlen -= ASCON_128A_RATE; 70 | } 71 | /* final plaintext block */ 72 | if (mlen >= 8) { 73 | s.x0 ^= LOADBYTES(m, 8); 74 | s.x1 ^= LOADBYTES(m + 8, mlen - 8); 75 | STOREBYTES(c, s.x0, 8); 76 | STOREBYTES(c + 8, s.x1, mlen - 8); 77 | s.x1 ^= PAD(mlen - 8); 78 | } else { 79 | s.x0 ^= LOADBYTES(m, mlen); 80 | STOREBYTES(c, s.x0, mlen); 81 | s.x0 ^= PAD(mlen); 82 | } 83 | c += mlen; 84 | printstate("process plaintext", &s); 85 | 86 | /* finalize */ 87 | s.x2 ^= K0; 88 | s.x3 ^= K1; 89 | P12(&s); 90 | s.x3 ^= K0; 91 | s.x4 ^= K1; 92 | printstate("finalization", &s); 93 | 94 | /* set tag */ 95 | STOREBYTES(c, s.x3, 8); 96 | STOREBYTES(c + 8, s.x4, 8); 97 | 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lwcrypto 2 |

3 | Go Reference 4 |

5 | 6 |

NIST Lightweight Cryptography

7 | 8 | This module implements NIST Lightweight Cryptography finalists. 9 | 10 | ## Installation 11 | 12 | Each implementation can be installed using Go modules. For 13 | example: 14 | 15 | ```bash 16 | go get github.com/ericlagergren/lwcrypto@latest 17 | ``` 18 | 19 | ## Usage 20 | 21 | The APIs conform to Go's `crypto/cipher` package. Note that the 22 | following example is not a substitute for reading the package's 23 | documentation. 24 | 25 | ```go 26 | package main 27 | 28 | import ( 29 | "crypto/rand" 30 | 31 | "github.com/ericlagergren/lwcrypto/ascon" 32 | ) 33 | 34 | func main() { 35 | // Keys must be KeySize bytes long. Anything else is an 36 | // error. 37 | key := make([]byte, ascon.KeySize) 38 | if _, err := rand.Read(key); err != nil { 39 | // rand.Read failing is almost always catastrophic. 40 | panic(err) 41 | } 42 | 43 | // Nonces must be NonceSize bytes long. Anything else is an 44 | // error. 45 | nonce := make([]byte, ascon.NonceSize) 46 | if _, err := rand.Read(nonce); err != nil { 47 | // rand.Read failing is almost always catastrophic. 48 | panic(err) 49 | } 50 | 51 | aead, err := ascon.New128(key) 52 | if err != nil { 53 | // New128 (and New128a) should only return an error if 54 | // the key is not KeySize bytes long. 55 | panic(err) 56 | } 57 | 58 | // Plaintext is encrypted and authenticated. 59 | plaintext := []byte("example plaintext") 60 | 61 | // Additional data is authenticated alongside the plaintext, 62 | // but not included in the ciphertext. 63 | additionalData := []byte("example additional authenticated data") 64 | 65 | // Encrypt and authenticate |plaintext| and authenticate 66 | // |additionalData|. 67 | ciphertext := aead.Seal(nil, nonce, plaintext, additionalData) 68 | 69 | // Decrypt and authentiate |ciphertext| and authenticate 70 | // |additionalData|. 71 | plaintext, err = aead.Open(nil, nonce, ciphertext, additionalData) 72 | if err != nil { 73 | // Authentication failed. Either the ciphertext or 74 | // additionalData (or both) were invalid for the 75 | // (key, nonce) pair. 76 | [...] 77 | } 78 | } 79 | ``` 80 | 81 | ## Security 82 | 83 | ### Disclosure 84 | 85 | This project uses full disclosure. If you find a security bug in 86 | an implementation, please e-mail me or create a GitHub issue. 87 | 88 | ### Disclaimer 89 | 90 | You should only use cryptography libraries that have been 91 | reviewed by cryptographers or cryptography engineers. While I am 92 | a cryptography engineer, I'm not your cryptography engineer, and 93 | I have not had this project reviewed by any other cryptographers. 94 | -------------------------------------------------------------------------------- /ascon/asm/go.sum: -------------------------------------------------------------------------------- 1 | github.com/mmcloughlin/avo v0.2.0 h1:6vhoSaKtxb6f4RiH+LK2qL6GSMpFzhEwJYTTSZNy09w= 2 | github.com/mmcloughlin/avo v0.2.0/go.mod h1:5tidO2Z9Z7N6X7UMcGg+1KTj51O8OxYDCMHxCZTVpEA= 3 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 4 | golang.org/x/arch v0.0.0-20210405154355-08b684f594a5/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= 5 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 6 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 7 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 8 | golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= 9 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 10 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 11 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 12 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 13 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 14 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 15 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 16 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 17 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 18 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 19 | golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A= 20 | golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 21 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 22 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 23 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 24 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 25 | golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= 26 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 27 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 28 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 29 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 30 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 31 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 32 | -------------------------------------------------------------------------------- /grain/asm/go.sum: -------------------------------------------------------------------------------- 1 | github.com/mmcloughlin/avo v0.2.0 h1:6vhoSaKtxb6f4RiH+LK2qL6GSMpFzhEwJYTTSZNy09w= 2 | github.com/mmcloughlin/avo v0.2.0/go.mod h1:5tidO2Z9Z7N6X7UMcGg+1KTj51O8OxYDCMHxCZTVpEA= 3 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 4 | golang.org/x/arch v0.0.0-20210405154355-08b684f594a5/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= 5 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 6 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 7 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 8 | golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= 9 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 10 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 11 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 12 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 13 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 14 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 15 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 16 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 17 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 18 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 19 | golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 20 | golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 h1:yhBbb4IRs2HS9PPlAg6DMC6mUOKexJBNsLf4Z+6En1Q= 21 | golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 22 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 23 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 24 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 25 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 26 | golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= 27 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 28 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 29 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 30 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 31 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 32 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 33 | -------------------------------------------------------------------------------- /ascon/internal/asconc/refa/decrypt.c: -------------------------------------------------------------------------------- 1 | #include "api.h" 2 | #include "ascon.h" 3 | #include "crypto_aead.h" 4 | #include "permutations.h" 5 | #include "printstate.h" 6 | #include "word.h" 7 | 8 | int crypto_aead_decrypt_a(unsigned char* m, unsigned long long* mlen, 9 | unsigned char* nsec, const unsigned char* c, 10 | unsigned long long clen, const unsigned char* ad, 11 | unsigned long long adlen, const unsigned char* npub, 12 | const unsigned char* k) { 13 | (void)nsec; 14 | 15 | if (clen < CRYPTO_ABYTES) return -1; 16 | 17 | /* set plaintext size */ 18 | *mlen = clen - CRYPTO_ABYTES; 19 | 20 | /* load key and nonce */ 21 | const uint64_t K0 = LOADBYTES(k, 8); 22 | const uint64_t K1 = LOADBYTES(k + 8, 8); 23 | const uint64_t N0 = LOADBYTES(npub, 8); 24 | const uint64_t N1 = LOADBYTES(npub + 8, 8); 25 | 26 | /* initialize */ 27 | state_t s; 28 | s.x0 = ASCON_128A_IV; 29 | s.x1 = K0; 30 | s.x2 = K1; 31 | s.x3 = N0; 32 | s.x4 = N1; 33 | P12(&s); 34 | s.x3 ^= K0; 35 | s.x4 ^= K1; 36 | printstate("initialization", &s); 37 | 38 | if (adlen) { 39 | /* full associated data blocks */ 40 | while (adlen >= ASCON_128A_RATE) { 41 | s.x0 ^= LOADBYTES(ad, 8); 42 | s.x1 ^= LOADBYTES(ad + 8, 8); 43 | P8(&s); 44 | ad += ASCON_128A_RATE; 45 | adlen -= ASCON_128A_RATE; 46 | } 47 | /* final associated data block */ 48 | if (adlen >= 8) { 49 | s.x0 ^= LOADBYTES(ad, 8); 50 | s.x1 ^= LOADBYTES(ad + 8, adlen - 8); 51 | s.x1 ^= PAD(adlen - 8); 52 | } else { 53 | s.x0 ^= LOADBYTES(ad, adlen); 54 | s.x0 ^= PAD(adlen); 55 | } 56 | P8(&s); 57 | } 58 | /* domain separation */ 59 | s.x4 ^= 1; 60 | printstate("process associated data", &s); 61 | 62 | /* full ciphertext blocks */ 63 | clen -= CRYPTO_ABYTES; 64 | while (clen >= ASCON_128A_RATE) { 65 | uint64_t c0 = LOADBYTES(c, 8); 66 | uint64_t c1 = LOADBYTES(c + 8, 8); 67 | STOREBYTES(m, s.x0 ^ c0, 8); 68 | STOREBYTES(m + 8, s.x1 ^ c1, 8); 69 | s.x0 = c0; 70 | s.x1 = c1; 71 | P8(&s); 72 | m += ASCON_128A_RATE; 73 | c += ASCON_128A_RATE; 74 | clen -= ASCON_128A_RATE; 75 | } 76 | /* final ciphertext block */ 77 | if (clen >= 8) { 78 | uint64_t c0 = LOADBYTES(c, 8); 79 | uint64_t c1 = LOADBYTES(c + 8, clen - 8); 80 | STOREBYTES(m, s.x0 ^ c0, 8); 81 | STOREBYTES(m + 8, s.x1 ^ c1, clen - 8); 82 | s.x0 = c0; 83 | s.x1 = CLEARBYTES(s.x1, clen - 8); 84 | s.x1 |= c1; 85 | s.x1 ^= PAD(clen - 8); 86 | } else { 87 | uint64_t c0 = LOADBYTES(c, clen); 88 | STOREBYTES(m, s.x0 ^ c0, clen); 89 | s.x0 = CLEARBYTES(s.x0, clen); 90 | s.x0 |= c0; 91 | s.x0 ^= PAD(clen); 92 | } 93 | c += clen; 94 | printstate("process ciphertext", &s); 95 | 96 | /* finalize */ 97 | s.x2 ^= K0; 98 | s.x3 ^= K1; 99 | P12(&s); 100 | s.x3 ^= K0; 101 | s.x4 ^= K1; 102 | printstate("finalization", &s); 103 | 104 | /* set tag */ 105 | uint8_t t[16]; 106 | STOREBYTES(t, s.x3, 8); 107 | STOREBYTES(t + 8, s.x4, 8); 108 | 109 | /* verify tag (should be constant time, check compiler output) */ 110 | int result = 0; 111 | for (int i = 0; i < CRYPTO_ABYTES; ++i) result |= c[i] ^ t[i]; 112 | result = (((result - 1) >> 8) & 1) - 1; 113 | 114 | return result; 115 | } 116 | -------------------------------------------------------------------------------- /ascon/internal/asconc/ref/permutations.h: -------------------------------------------------------------------------------- 1 | #ifndef PERMUTATIONS_H_ 2 | #define PERMUTATIONS_H_ 3 | 4 | #include 5 | 6 | #include "ascon.h" 7 | #include "printstate.h" 8 | #include "round.h" 9 | 10 | #define ASCON_128_KEYBYTES 16 11 | #define ASCON_128A_KEYBYTES 16 12 | #define ASCON_80PQ_KEYBYTES 20 13 | 14 | #define ASCON_128_RATE 8 15 | #define ASCON_128A_RATE 16 16 | #define ASCON_HASH_RATE 8 17 | 18 | #define ASCON_128_PA_ROUNDS 12 19 | #define ASCON_128_PB_ROUNDS 6 20 | 21 | #define ASCON_128A_PA_ROUNDS 12 22 | #define ASCON_128A_PB_ROUNDS 8 23 | 24 | #define ASCON_HASH_PA_ROUNDS 12 25 | #define ASCON_HASH_PB_ROUNDS 12 26 | 27 | #define ASCON_HASHA_PA_ROUNDS 12 28 | #define ASCON_HASHA_PB_ROUNDS 8 29 | 30 | #define ASCON_HASH_BYTES 32 31 | 32 | #define ASCON_128_IV \ 33 | (((uint64_t)(ASCON_128_KEYBYTES * 8) << 56) | \ 34 | ((uint64_t)(ASCON_128_RATE * 8) << 48) | \ 35 | ((uint64_t)(ASCON_128_PA_ROUNDS) << 40) | \ 36 | ((uint64_t)(ASCON_128_PB_ROUNDS) << 32)) 37 | 38 | #define ASCON_128A_IV \ 39 | (((uint64_t)(ASCON_128A_KEYBYTES * 8) << 56) | \ 40 | ((uint64_t)(ASCON_128A_RATE * 8) << 48) | \ 41 | ((uint64_t)(ASCON_128A_PA_ROUNDS) << 40) | \ 42 | ((uint64_t)(ASCON_128A_PB_ROUNDS) << 32)) 43 | 44 | #define ASCON_80PQ_IV \ 45 | (((uint64_t)(ASCON_80PQ_KEYBYTES * 8) << 56) | \ 46 | ((uint64_t)(ASCON_128_RATE * 8) << 48) | \ 47 | ((uint64_t)(ASCON_128_PA_ROUNDS) << 40) | \ 48 | ((uint64_t)(ASCON_128_PB_ROUNDS) << 32)) 49 | 50 | #define ASCON_HASH_IV \ 51 | (((uint64_t)(ASCON_HASH_RATE * 8) << 48) | \ 52 | ((uint64_t)(ASCON_HASH_PA_ROUNDS) << 40) | \ 53 | ((uint64_t)(ASCON_HASH_PA_ROUNDS - ASCON_HASH_PB_ROUNDS) << 32) | \ 54 | ((uint64_t)(ASCON_HASH_BYTES * 8) << 0)) 55 | 56 | #define ASCON_HASHA_IV \ 57 | (((uint64_t)(ASCON_HASH_RATE * 8) << 48) | \ 58 | ((uint64_t)(ASCON_HASHA_PA_ROUNDS) << 40) | \ 59 | ((uint64_t)(ASCON_HASHA_PA_ROUNDS - ASCON_HASHA_PB_ROUNDS) << 32) | \ 60 | ((uint64_t)(ASCON_HASH_BYTES * 8) << 0)) 61 | 62 | #define ASCON_XOF_IV \ 63 | (((uint64_t)(ASCON_HASH_RATE * 8) << 48) | \ 64 | ((uint64_t)(ASCON_HASH_PA_ROUNDS) << 40) | \ 65 | ((uint64_t)(ASCON_HASH_PA_ROUNDS - ASCON_HASH_PB_ROUNDS) << 32)) 66 | 67 | #define ASCON_XOFA_IV \ 68 | (((uint64_t)(ASCON_HASH_RATE * 8) << 48) | \ 69 | ((uint64_t)(ASCON_HASHA_PA_ROUNDS) << 40) | \ 70 | ((uint64_t)(ASCON_HASHA_PA_ROUNDS - ASCON_HASHA_PB_ROUNDS) << 32)) 71 | 72 | static inline void P12(state_t* s) { 73 | printstate(" permutation input", s); 74 | ROUND(s, 0xf0); 75 | ROUND(s, 0xe1); 76 | ROUND(s, 0xd2); 77 | ROUND(s, 0xc3); 78 | ROUND(s, 0xb4); 79 | ROUND(s, 0xa5); 80 | ROUND(s, 0x96); 81 | ROUND(s, 0x87); 82 | ROUND(s, 0x78); 83 | ROUND(s, 0x69); 84 | ROUND(s, 0x5a); 85 | ROUND(s, 0x4b); 86 | } 87 | 88 | static inline void P8(state_t* s) { 89 | printstate(" permutation input", s); 90 | ROUND(s, 0xb4); 91 | ROUND(s, 0xa5); 92 | ROUND(s, 0x96); 93 | ROUND(s, 0x87); 94 | ROUND(s, 0x78); 95 | ROUND(s, 0x69); 96 | ROUND(s, 0x5a); 97 | ROUND(s, 0x4b); 98 | } 99 | 100 | static inline void P6(state_t* s) { 101 | printstate(" permutation input", s); 102 | ROUND(s, 0x96); 103 | ROUND(s, 0x87); 104 | ROUND(s, 0x78); 105 | ROUND(s, 0x69); 106 | ROUND(s, 0x5a); 107 | ROUND(s, 0x4b); 108 | } 109 | 110 | #endif /* PERMUTATIONS_H_ */ 111 | -------------------------------------------------------------------------------- /ascon/internal/asconc/refa/permutations.h: -------------------------------------------------------------------------------- 1 | #ifndef PERMUTATIONS_H_ 2 | #define PERMUTATIONS_H_ 3 | 4 | #include 5 | 6 | #include "ascon.h" 7 | #include "printstate.h" 8 | #include "round.h" 9 | 10 | #define ASCON_128_KEYBYTES 16 11 | #define ASCON_128A_KEYBYTES 16 12 | #define ASCON_80PQ_KEYBYTES 20 13 | 14 | #define ASCON_128_RATE 8 15 | #define ASCON_128A_RATE 16 16 | #define ASCON_HASH_RATE 8 17 | 18 | #define ASCON_128_PA_ROUNDS 12 19 | #define ASCON_128_PB_ROUNDS 6 20 | 21 | #define ASCON_128A_PA_ROUNDS 12 22 | #define ASCON_128A_PB_ROUNDS 8 23 | 24 | #define ASCON_HASH_PA_ROUNDS 12 25 | #define ASCON_HASH_PB_ROUNDS 12 26 | 27 | #define ASCON_HASHA_PA_ROUNDS 12 28 | #define ASCON_HASHA_PB_ROUNDS 8 29 | 30 | #define ASCON_HASH_BYTES 32 31 | 32 | #define ASCON_128_IV \ 33 | (((uint64_t)(ASCON_128_KEYBYTES * 8) << 56) | \ 34 | ((uint64_t)(ASCON_128_RATE * 8) << 48) | \ 35 | ((uint64_t)(ASCON_128_PA_ROUNDS) << 40) | \ 36 | ((uint64_t)(ASCON_128_PB_ROUNDS) << 32)) 37 | 38 | #define ASCON_128A_IV \ 39 | (((uint64_t)(ASCON_128A_KEYBYTES * 8) << 56) | \ 40 | ((uint64_t)(ASCON_128A_RATE * 8) << 48) | \ 41 | ((uint64_t)(ASCON_128A_PA_ROUNDS) << 40) | \ 42 | ((uint64_t)(ASCON_128A_PB_ROUNDS) << 32)) 43 | 44 | #define ASCON_80PQ_IV \ 45 | (((uint64_t)(ASCON_80PQ_KEYBYTES * 8) << 56) | \ 46 | ((uint64_t)(ASCON_128_RATE * 8) << 48) | \ 47 | ((uint64_t)(ASCON_128_PA_ROUNDS) << 40) | \ 48 | ((uint64_t)(ASCON_128_PB_ROUNDS) << 32)) 49 | 50 | #define ASCON_HASH_IV \ 51 | (((uint64_t)(ASCON_HASH_RATE * 8) << 48) | \ 52 | ((uint64_t)(ASCON_HASH_PA_ROUNDS) << 40) | \ 53 | ((uint64_t)(ASCON_HASH_PA_ROUNDS - ASCON_HASH_PB_ROUNDS) << 32) | \ 54 | ((uint64_t)(ASCON_HASH_BYTES * 8) << 0)) 55 | 56 | #define ASCON_HASHA_IV \ 57 | (((uint64_t)(ASCON_HASH_RATE * 8) << 48) | \ 58 | ((uint64_t)(ASCON_HASHA_PA_ROUNDS) << 40) | \ 59 | ((uint64_t)(ASCON_HASHA_PA_ROUNDS - ASCON_HASHA_PB_ROUNDS) << 32) | \ 60 | ((uint64_t)(ASCON_HASH_BYTES * 8) << 0)) 61 | 62 | #define ASCON_XOF_IV \ 63 | (((uint64_t)(ASCON_HASH_RATE * 8) << 48) | \ 64 | ((uint64_t)(ASCON_HASH_PA_ROUNDS) << 40) | \ 65 | ((uint64_t)(ASCON_HASH_PA_ROUNDS - ASCON_HASH_PB_ROUNDS) << 32)) 66 | 67 | #define ASCON_XOFA_IV \ 68 | (((uint64_t)(ASCON_HASH_RATE * 8) << 48) | \ 69 | ((uint64_t)(ASCON_HASHA_PA_ROUNDS) << 40) | \ 70 | ((uint64_t)(ASCON_HASHA_PA_ROUNDS - ASCON_HASHA_PB_ROUNDS) << 32)) 71 | 72 | static inline void P12(state_t* s) { 73 | printstate(" permutation input", s); 74 | ROUND(s, 0xf0); 75 | ROUND(s, 0xe1); 76 | ROUND(s, 0xd2); 77 | ROUND(s, 0xc3); 78 | ROUND(s, 0xb4); 79 | ROUND(s, 0xa5); 80 | ROUND(s, 0x96); 81 | ROUND(s, 0x87); 82 | ROUND(s, 0x78); 83 | ROUND(s, 0x69); 84 | ROUND(s, 0x5a); 85 | ROUND(s, 0x4b); 86 | } 87 | 88 | static inline void P8(state_t* s) { 89 | printstate(" permutation input", s); 90 | ROUND(s, 0xb4); 91 | ROUND(s, 0xa5); 92 | ROUND(s, 0x96); 93 | ROUND(s, 0x87); 94 | ROUND(s, 0x78); 95 | ROUND(s, 0x69); 96 | ROUND(s, 0x5a); 97 | ROUND(s, 0x4b); 98 | } 99 | 100 | static inline void P6(state_t* s) { 101 | printstate(" permutation input", s); 102 | ROUND(s, 0x96); 103 | ROUND(s, 0x87); 104 | ROUND(s, 0x78); 105 | ROUND(s, 0x69); 106 | ROUND(s, 0x5a); 107 | ROUND(s, 0x4b); 108 | } 109 | 110 | #endif /* PERMUTATIONS_H_ */ 111 | -------------------------------------------------------------------------------- /ascon/internal/cmd/pgen/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "go/format" 7 | "os" 8 | ) 9 | 10 | func main() { 11 | if err := main1(); err != nil { 12 | panic(err) 13 | } 14 | } 15 | 16 | func main1() error { 17 | var b bytes.Buffer 18 | b.WriteString("// Code generated by pgen.go. DO NOT EDIT.\n\n") 19 | b.WriteString("package ascon\n") 20 | b.WriteString(`import ( 21 | "encoding/binary" 22 | "math/bits" 23 | ) 24 | `) 25 | 26 | genAD(&b) 27 | genEncrypt(&b) 28 | genDecrypt(&b) 29 | genRound(&b) 30 | 31 | // Generate the permutations. 32 | for _, nr := range []int{6, 8, 12} { 33 | fmt.Fprintf(&b, "func p%dGeneric(s *state) {\n", nr) 34 | b.WriteString(load) 35 | pbody(&b, nr) 36 | b.WriteString(store) 37 | b.WriteString("}\n\n") 38 | } 39 | 40 | buf, err := format.Source(b.Bytes()) 41 | if err != nil { 42 | fmt.Println(b.String()) 43 | return err 44 | } 45 | return os.WriteFile("zascon_generic.go", buf, 0644) 46 | } 47 | 48 | func genAD(b *bytes.Buffer) { 49 | b.WriteString("func additionalData128aGeneric(s *state, ad []byte) {\n") 50 | b.WriteString(load) 51 | b.WriteString("for len(ad) >= BlockSize128a {\n") 52 | b.WriteString("s0 ^= binary.BigEndian.Uint64(ad[0:8])\n") 53 | b.WriteString("s1 ^= binary.BigEndian.Uint64(ad[8:16])\n") 54 | pbody(b, 8) 55 | b.WriteString("ad = ad[BlockSize128a:]\n") 56 | b.WriteString("}\n") 57 | b.WriteString(store) 58 | b.WriteString("}\n\n") 59 | } 60 | 61 | func genEncrypt(b *bytes.Buffer) { 62 | b.WriteString("func encryptBlocks128aGeneric(s *state, dst, src []byte) {\n") 63 | b.WriteString(load) 64 | b.WriteString("for len(src) >= BlockSize128a && len(dst) >= BlockSize128a {\n") 65 | b.WriteString("s0 ^= binary.BigEndian.Uint64(src[0:8])\n") 66 | b.WriteString("s1 ^= binary.BigEndian.Uint64(src[8:16])\n") 67 | b.WriteString("binary.BigEndian.PutUint64(dst[0:8], s0)\n") 68 | b.WriteString("binary.BigEndian.PutUint64(dst[8:16], s1)\n") 69 | pbody(b, 8) 70 | b.WriteString("src = src[BlockSize128a:]\n") 71 | b.WriteString("dst = dst[BlockSize128a:]\n") 72 | b.WriteString("}\n") 73 | b.WriteString(store) 74 | b.WriteString("}\n\n") 75 | } 76 | 77 | func genDecrypt(b *bytes.Buffer) { 78 | b.WriteString("func decryptBlocks128aGeneric(s *state, dst, src []byte) {\n") 79 | b.WriteString(load) 80 | b.WriteString("for len(src) >= BlockSize128a && len(dst) >= BlockSize128a {\n") 81 | b.WriteString("c0 := binary.BigEndian.Uint64(src[0:8])\n") 82 | b.WriteString("c1 := binary.BigEndian.Uint64(src[8:16])\n") 83 | b.WriteString("binary.BigEndian.PutUint64(dst[0:8], s0^c0)\n") 84 | b.WriteString("binary.BigEndian.PutUint64(dst[8:16], s1^c1)\n") 85 | b.WriteString("s0, s1 = c0, c1\n") 86 | pbody(b, 8) 87 | b.WriteString("src = src[BlockSize128a:]\n") 88 | b.WriteString("dst = dst[BlockSize128a:]\n") 89 | b.WriteString("}\n") 90 | b.WriteString(store) 91 | b.WriteString("}\n\n") 92 | } 93 | 94 | func genRound(b *bytes.Buffer) { 95 | b.WriteString("func roundGeneric(s *state, C uint64) {\n") 96 | b.WriteString(load) 97 | b.WriteString(roundBody) 98 | b.WriteString(store) 99 | b.WriteString("}\n\n") 100 | } 101 | 102 | // pbody generates the body of a permutation. 103 | func pbody(b *bytes.Buffer, nr int) { 104 | start := ((3+nr)<<4 | (12 - nr)) 105 | fmt.Fprintf(b, "for C := uint64(%d); C >= 74; C -= 15 {\n", start) 106 | b.WriteString(roundBody) 107 | b.WriteString("}\n") 108 | } 109 | 110 | const load = `s0 := s.x0 111 | s1 := s.x1 112 | s2 := s.x2 113 | s3 := s.x3 114 | s4 := s.x4 115 | ` 116 | 117 | const store = `s.x0 = s0 118 | s.x1 = s1 119 | s.x2 = s2 120 | s.x3 = s3 121 | s.x4 = s4 122 | ` 123 | 124 | const roundBody = `// Round constant 125 | s2 ^= C 126 | 127 | // Substitution 128 | s0 ^= s4 129 | s4 ^= s3 130 | s2 ^= s1 131 | 132 | // Keccak S-box 133 | t0 := s0 ^ (^s1 & s2) 134 | t1 := s1 ^ (^s2 & s3) 135 | t2 := s2 ^ (^s3 & s4) 136 | t3 := s3 ^ (^s4 & s0) 137 | t4 := s4 ^ (^s0 & s1) 138 | 139 | // Substitution 140 | t1 ^= t0 141 | t0 ^= t4 142 | t3 ^= t2 143 | t2 = ^t2 144 | 145 | // Linear diffusion 146 | // 147 | // x0 ← Σ0(x0) = x0 ⊕ (x0 ≫ 19) ⊕ (x0 ≫ 28) 148 | s0 = t0 ^ bits.RotateLeft64(t0, -19) ^ bits.RotateLeft64(t0, -28) 149 | // x1 ← Σ1(x1) = x1 ⊕ (x1 ≫ 61) ⊕ (x1 ≫ 39) 150 | s1 = t1 ^ bits.RotateLeft64(t1, -61) ^ bits.RotateLeft64(t1, -39) 151 | // x2 ← Σ2(x2) = x2 ⊕ (x2 ≫ 1) ⊕ (x2 ≫ 6) 152 | s2 = t2 ^ bits.RotateLeft64(t2, -1) ^ bits.RotateLeft64(t2, -6) 153 | // x3 ← Σ3(x3) = x3 ⊕ (x3 ≫ 10) ⊕ (x3 ≫ 17) 154 | s3 = t3 ^ bits.RotateLeft64(t3, -10) ^ bits.RotateLeft64(t3, -17) 155 | // x4 ← Σ4(x4) = x4 ⊕ (x4 ≫ 7) ⊕ (x4 ≫ 41) 156 | s4 = t4 ^ bits.RotateLeft64(t4, -7) ^ bits.RotateLeft64(t4, -41) 157 | ` 158 | -------------------------------------------------------------------------------- /ascon/asm/asm.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | . "github.com/mmcloughlin/avo/build" 5 | "github.com/mmcloughlin/avo/ir" 6 | . "github.com/mmcloughlin/avo/operand" 7 | . "github.com/mmcloughlin/avo/reg" 8 | ) 9 | 10 | //go:generate go run asm.go -out ../ascon_amd64.s -stubs ../stub_amd64.go -pkg ascon 11 | 12 | func main() { 13 | Package("github.com/ericlagergren/lwcrypto/ascon") 14 | ConstraintExpr("gc,!purego") 15 | 16 | declarePermute() 17 | declareRound() 18 | declareAdditionalData128a() 19 | declareEncryptBlocks128a() 20 | declareDecryptBlocks128a() 21 | 22 | Generate() 23 | } 24 | 25 | func declareAdditionalData128a() { 26 | TEXT("additionalData128a", NOSPLIT, "func(s *state, ad []byte)") 27 | Pragma("noescape") 28 | Instruction(&ir.Instruction{ 29 | Opcode: "JMP", 30 | Operands: []Op{LabelRef("·additionalData128aGeneric(SB)")}, 31 | }) 32 | RET() 33 | } 34 | 35 | func declareEncryptBlocks128a() { 36 | TEXT("encryptBlocks128a", NOSPLIT, "func(s *state, dst, src []byte)") 37 | Pragma("noescape") 38 | Instruction(&ir.Instruction{ 39 | Opcode: "JMP", 40 | Operands: []Op{LabelRef("·encryptBlocks128aGeneric(SB)")}, 41 | }) 42 | RET() 43 | } 44 | 45 | func declareDecryptBlocks128a() { 46 | TEXT("decryptBlocks128a", NOSPLIT, "func(s *state, dst, src []byte)") 47 | Pragma("noescape") 48 | Instruction(&ir.Instruction{ 49 | Opcode: "JMP", 50 | Operands: []Op{LabelRef("·decryptBlocks128aGeneric(SB)")}, 51 | }) 52 | RET() 53 | } 54 | 55 | func declarePermute() { 56 | for _, v := range []struct { 57 | name string 58 | rc []uint32 59 | }{ 60 | {"p12", p12}, 61 | {"p8", p8}, 62 | {"p6", p6}, 63 | } { 64 | TEXT(v.name, NOSPLIT, "func(s *state)") 65 | Pragma("noescape") 66 | p := Load(Param("s"), GP64()) 67 | s := loadState(Mem{Base: p}) 68 | permute(v.rc, s) 69 | storeState(s, Mem{Base: p}) 70 | RET() 71 | } 72 | } 73 | 74 | func declareRound() { 75 | TEXT("round", NOSPLIT, "func(s *state, C uint64)") 76 | Pragma("noescape") 77 | 78 | p := Load(Param("s"), GP64()) 79 | s := loadState(Mem{Base: p}) 80 | C := Load(Param("C"), GP64()) 81 | round(s, C) 82 | storeState(s, Mem{Base: p}) 83 | RET() 84 | } 85 | 86 | func loadState(m Mem) state { 87 | s := state{ 88 | 0: GP64(), 89 | 1: GP64(), 90 | 2: GP64(), 91 | 3: GP64(), 92 | 4: GP64(), 93 | } 94 | for i, r := range s { 95 | MOVQ(m.Offset(i*8), r) 96 | } 97 | return s 98 | } 99 | 100 | func storeState(s state, m Mem) { 101 | for i, r := range s { 102 | MOVQ(r, m.Offset(i*8)) 103 | } 104 | } 105 | 106 | var ( 107 | p12 = []uint32{ 108 | 0xf0, 0xe1, 0xd2, 0xc3, 109 | 0xb4, 0xa5, 0x96, 0x87, 110 | 0x78, 0x69, 0x5a, 0x4b, 111 | } 112 | p8 = []uint32{ 113 | 0xb4, 0xa5, 0x96, 0x87, 114 | 0x78, 0x69, 0x5a, 0x4b, 115 | } 116 | p6 = []uint32{0x96, 0x87, 0x78, 0x69, 0x5a, 0x4b} 117 | ) 118 | 119 | func permute(rc []uint32, s state) { 120 | for i, C := range rc { 121 | Commentf("Start round %d", i+1) 122 | round(s, U32(C)) 123 | Commentf("End round %d\n", i+1) 124 | } 125 | } 126 | 127 | // round outputs the ASCON round function. 128 | // 129 | // C must be either a Register or int. 130 | func round(s state, C Op) { 131 | Comment("Round constant") 132 | XORQ(C, s[2]) 133 | 134 | Comment("Substitution") 135 | XORQ(s[4], s[0]) // s[0] ^= s[4] 136 | XORQ(s[3], s[4]) // s[4] ^= s[3] 137 | XORQ(s[1], s[2]) // s[2] ^= s[1] 138 | 139 | Comment("Keccak S-box") 140 | var t state 141 | t[0] = sbox(GP64(), s[0], s[1], s[2]) 142 | t[1] = sbox(GP64(), s[1], s[2], s[3]) 143 | t[2] = sbox(GP64(), s[2], s[3], s[4]) 144 | t[3] = sbox(GP64(), s[3], s[4], s[0]) 145 | t[4] = sbox(GP64(), s[4], s[0], s[1]) 146 | 147 | Comment("Substituton") 148 | XORQ(t[0], t[1]) // t[1] ^= t[0] 149 | XORQ(t[4], t[0]) // t[0] ^= t[4] 150 | XORQ(t[2], t[3]) // t[3] ^= t[2] 151 | NOTQ(t[2]) // t[2] = ^t[2] 152 | 153 | Comment("Linear diffusion") 154 | ldiff(s[0], t[0], 19, 28) 155 | ldiff(s[1], t[1], 61, 39) 156 | ldiff(s[2], t[2], 1, 6) 157 | ldiff(s[3], t[3], 10, 17) 158 | ldiff(s[4], t[4], 7, 41) 159 | } 160 | 161 | // sbox sets z = a ^ (^b & c) and returns z. 162 | func sbox(z, a, b, c Register) Register { 163 | nb := GP64() 164 | MOVQ(b, nb) 165 | NOTQ(nb) // b = ^b 166 | MOVQ(c, z) // z = c 167 | ANDQ(nb, z) // z = ^b & c 168 | XORQ(a, z) // z = a ^ z 169 | return z 170 | } 171 | 172 | // ldiff sets z = x ^ rotr(x, n0) ^ rotr(x, n1). 173 | func ldiff(z, x Register, n0, n1 uint64) { 174 | // z = rotr(x, n0) 175 | MOVQ(x, z) 176 | RORQ(U8(n0), z) 177 | 178 | // z = x ^ z 179 | XORQ(x, z) 180 | 181 | // t = rotr(x, n0) 182 | t := GP64() 183 | MOVQ(x, t) 184 | RORQ(U8(n1), t) 185 | 186 | XORQ(t, z) // z = z ^ t 187 | } 188 | 189 | type state [5]Register 190 | -------------------------------------------------------------------------------- /ascon/ascon_test.go: -------------------------------------------------------------------------------- 1 | package ascon 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "crypto/cipher" 7 | "encoding/hex" 8 | "fmt" 9 | "math/rand" 10 | "os" 11 | "path/filepath" 12 | "reflect" 13 | "strings" 14 | "testing" 15 | "testing/quick" 16 | ) 17 | 18 | var stateType = reflect.TypeOf([5]uint64{}) 19 | 20 | func randState(rng *rand.Rand) state { 21 | v, ok := quick.Value(stateType, rng) 22 | if !ok { 23 | panic("got false") 24 | } 25 | x := v.Interface().([5]uint64) 26 | return state{ 27 | x0: x[0], 28 | x1: x[1], 29 | x2: x[2], 30 | x3: x[3], 31 | x4: x[4], 32 | } 33 | } 34 | 35 | func TestRound(t *testing.T) { 36 | rng := rand.New(rand.NewSource(0xDEADBEEF)) 37 | for i := 0; i < 1000; i++ { 38 | s := randState(rng) 39 | want, got := s, s 40 | C := uint64(i) 41 | roundGeneric(&want, C) 42 | round(&got, C) 43 | if want != got { 44 | t.Fatalf("expected %v, got %v", want, got) 45 | } 46 | } 47 | } 48 | 49 | func TestPermute(t *testing.T) { 50 | for _, tc := range []struct { 51 | name string 52 | fn func(*state) 53 | fnGeneric func(*state) 54 | }{ 55 | {"p12", p12, p12Generic}, 56 | {"p8", p8, p8Generic}, 57 | {"p6", p6, p6Generic}, 58 | } { 59 | rng := rand.New(rand.NewSource(0xDEADBEEF)) 60 | t.Run(tc.name, func(t *testing.T) { 61 | for i := 0; i < 1000; i++ { 62 | s := randState(rng) 63 | want, got := s, s 64 | tc.fnGeneric(&want) 65 | tc.fn(&got) 66 | if want != got { 67 | t.Fatalf("#%d: expected %v, got %v", i, want, got) 68 | } 69 | } 70 | }) 71 | } 72 | } 73 | 74 | func TestVectors128(t *testing.T) { 75 | testVectors(t, New128, filepath.Join("testdata", "vectors_128.txt")) 76 | } 77 | 78 | func TestVectors128a(t *testing.T) { 79 | testVectors(t, New128a, filepath.Join("testdata", "vectors_128a.txt")) 80 | } 81 | 82 | func testVectors(t *testing.T, fn func([]byte) (cipher.AEAD, error), path string) { 83 | vecs, err := readVecs(path) 84 | if err != nil { 85 | t.Fatal(err) 86 | } 87 | for i, v := range vecs { 88 | c, err := fn(v.key) 89 | if err != nil { 90 | t.Fatalf("#%d: %v", i+1, err) 91 | } 92 | ciphertext := c.Seal(nil, v.nonce, v.pt, v.ad) 93 | if !bytes.Equal(ciphertext, v.ct) { 94 | t.Fatalf("#%d: expected %#x, got %#x", i+1, v.ct, ciphertext) 95 | } 96 | plaintext, err := c.Open(nil, v.nonce, v.ct, v.ad) 97 | if err != nil { 98 | t.Fatalf("#%d: %v", i+1, err) 99 | } 100 | if !bytes.Equal(plaintext, v.pt) { 101 | t.Fatalf("#%d: expected %#x, got %#x", i+1, v.pt, plaintext) 102 | } 103 | } 104 | } 105 | 106 | func BenchmarkSeal1K_128a(b *testing.B) { 107 | benchmarkSeal(b, New128a, make([]byte, 1024)) 108 | } 109 | 110 | func BenchmarkOpen1K_128a(b *testing.B) { 111 | benchmarkOpen(b, New128a, make([]byte, 1024)) 112 | } 113 | 114 | func BenchmarkSeal8K_128a(b *testing.B) { 115 | benchmarkSeal(b, New128a, make([]byte, 8*1024)) 116 | } 117 | 118 | func BenchmarkOpen8K_128a(b *testing.B) { 119 | benchmarkOpen(b, New128a, make([]byte, 8*1024)) 120 | } 121 | 122 | func BenchmarkSeal1K_128(b *testing.B) { 123 | benchmarkSeal(b, New128, make([]byte, 1024)) 124 | } 125 | 126 | func BenchmarkOpen1K_128(b *testing.B) { 127 | benchmarkOpen(b, New128, make([]byte, 1024)) 128 | } 129 | 130 | func BenchmarkSeal8K_128(b *testing.B) { 131 | benchmarkSeal(b, New128, make([]byte, 8*1024)) 132 | } 133 | 134 | func BenchmarkOpen8K_128(b *testing.B) { 135 | benchmarkOpen(b, New128, make([]byte, 8*1024)) 136 | } 137 | 138 | func benchmarkSeal(b *testing.B, fn func([]byte) (cipher.AEAD, error), buf []byte) { 139 | b.SetBytes(int64(len(buf))) 140 | 141 | key := make([]byte, KeySize) 142 | nonce := make([]byte, NonceSize) 143 | ad := make([]byte, 13) 144 | aead, err := fn(key) 145 | if err != nil { 146 | b.Fatal(err) 147 | } 148 | var out []byte 149 | 150 | b.ResetTimer() 151 | for i := 0; i < b.N; i++ { 152 | out = aead.Seal(out[:0], nonce, buf, ad) 153 | } 154 | } 155 | 156 | func benchmarkOpen(b *testing.B, fn func([]byte) (cipher.AEAD, error), buf []byte) { 157 | b.SetBytes(int64(len(buf))) 158 | 159 | key := make([]byte, KeySize) 160 | nonce := make([]byte, NonceSize) 161 | ad := make([]byte, 13) 162 | aead, err := fn(key) 163 | if err != nil { 164 | b.Fatal(err) 165 | } 166 | var out []byte 167 | out = aead.Seal(out[:0], nonce, buf, ad) 168 | 169 | b.ResetTimer() 170 | for i := 0; i < b.N; i++ { 171 | _, err := aead.Open(buf[:0], nonce, out, ad) 172 | if err != nil { 173 | b.Errorf("Open: %v", err) 174 | } 175 | } 176 | } 177 | 178 | type vector struct { 179 | key []byte 180 | nonce []byte 181 | pt []byte 182 | ad []byte 183 | ct []byte 184 | } 185 | 186 | func (v *vector) set(field string, p []byte) bool { 187 | switch field { 188 | case "Key": 189 | v.key = p 190 | case "Nonce": 191 | v.nonce = p 192 | case "PT": 193 | v.pt = p 194 | case "AD": 195 | v.ad = p 196 | case "CT": 197 | v.ct = p 198 | default: 199 | return false 200 | } 201 | return true 202 | } 203 | 204 | func readVecs(path string) ([]vector, error) { 205 | f, err := os.Open(path) 206 | if err != nil { 207 | return nil, err 208 | } 209 | defer f.Close() 210 | 211 | var vecs []vector 212 | 213 | s := bufio.NewScanner(f) 214 | for i := 0; s.Scan(); i++ { 215 | t := s.Text() 216 | if t == "" { 217 | continue 218 | } 219 | if strings.HasPrefix(t, "Count = ") { 220 | vecs = append(vecs, vector{}) 221 | continue 222 | } 223 | i := strings.IndexByte(t, '=') 224 | if i < 0 { 225 | return nil, fmt.Errorf("malformed line %d: %q", i+1, t) 226 | } 227 | data := strings.TrimSpace(t[i+1:]) 228 | buf, err := hex.DecodeString(data) 229 | if err != nil { 230 | return nil, fmt.Errorf("malformed line %d: %v", i+1, err) 231 | } 232 | field := strings.TrimSpace(t[:i]) 233 | if !vecs[len(vecs)-1].set(field, buf) { 234 | return nil, fmt.Errorf("malformed line %d: %q", i+1, t) 235 | } 236 | } 237 | return vecs, nil 238 | } 239 | -------------------------------------------------------------------------------- /ascon/ascon_arm64.s: -------------------------------------------------------------------------------- 1 | //go:build gc && !purego 2 | // +build gc,!purego 3 | 4 | #include "textflag.h" 5 | 6 | // R0-R10 are reserved for permutations. 7 | 8 | #define s0 R0 9 | #define s1 R1 10 | #define s2 R2 11 | #define s3 R3 12 | #define s4 R4 13 | 14 | #define t0 R5 15 | #define t1 R6 16 | #define t2 R7 17 | #define t3 R8 18 | #define t4 R9 19 | 20 | #define s_ptr R10 21 | 22 | // PERM_LOAD loads *state from s+0(FP) into s_ptr. 23 | #define PERM_LOAD \ 24 | MOVD s+0(FP), s_ptr; \ 25 | LDP 0*16(s_ptr), (s0, s1); \ 26 | LDP 1*16(s_ptr), (s2, s3); \ 27 | MOVD 2*16(s_ptr), s4 28 | 29 | // PERM_STORE stores s{0,1,2,4} into s_ptr. 30 | #define PERM_STORE \ 31 | STP (s0, s1), 0*16(s_ptr); \ 32 | STP (s2, s3), 1*16(s_ptr); \ 33 | MOVD s4, 2*16(s_ptr) 34 | 35 | // ROUND completes one permutation round. 36 | // 37 | // Uses s{0,1,2,3,4} and t{0,1,2,3,4}. 38 | #define ROUND(C) \ 39 | EOR C, s2, s2 /* s2 ^= C */ \ 40 | \ 41 | EOR s4, s0, s0 /* s0 ^= s4 */ \ 42 | EOR s3, s4, s4 /* s4 ^= s3 */ \ 43 | EOR s1, s2, s2 /* s2 ^= s1 */ \ 44 | \ 45 | BIC s1, s2, t0 /* t0 := ^s1 & s2 */ \ 46 | BIC s3, s4, t2 /* t2 := ^s3 & s4 */ \ 47 | BIC s0, s1, t4 /* t4 := ^s0 & s1 */ \ 48 | BIC s2, s3, t1 /* t1 := ^s2 & s3 */ \ 49 | BIC s4, s0, t3 /* t3 := ^s4 & s0 */ \ 50 | \ 51 | EOR s0, t0, t0 /* t0 ^= s0 */ \ 52 | EOR s1, t1, t1 /* t1 ^= s1*/ \ 53 | EOR s2, t2, t2 /* t2 ^= s2 */ \ 54 | EOR s3, t3, t3 /* t3 ^= s3 */ \ 55 | EOR s4, t4, t4 /* t4 ^= s4 */ \ 56 | \ 57 | EOR t0, t1, t1 /* t1 ^= t0 */ \ 58 | EOR t2, t3, t3 /* t3 ^= t2 */ \ 59 | EOR t4, t0, t0 /* t0 ^= t4 */ \ 60 | \ 61 | EOR t2@>6-1, t2, s2 /* s2 = t2 ^ rotr(t2, 6-1) */ \ 62 | EOR t3@>17-10, t3, s3 /* s3 = t3 ^ rotr(t3, 17-10) */ \ 63 | EOR t4@>41-7, t4, s4 /* s4 = t4 ^ rotr(t4, 41-8) */ \ 64 | EOR t0@>28-19, t0, s0 /* s0 = t0 ^ rotr(t0, 28-19) */ \ 65 | EOR t1@>61-39, t1, s1 /* s1 = t1 ^ rotr(t1, 61-39) */ \ 66 | \ 67 | EOR s3@>10, t3, s3 /* s3 = t3 ^ rotr(s3, 10) */ \ 68 | EOR s4@>7, t4, s4 /* s4 = t4 ^ rotr(s4, 7) */ \ 69 | EOR s0@>19, t0, s0 /* s0 = t0 ^ rotr(s0, 19) */ \ 70 | EOR s1@>39, t1, s1 /* s1 = t1 ^ rotr(s1, 39) */ \ 71 | EON s2@>1, t2, s2 /* s2 = t2 ^ rotr(s2, 1) */ \ 72 | \ 73 | /* So the comments line up correctly */ \ 74 | NOP 75 | 76 | #define P12 \ 77 | ROUND($0xf0); \ 78 | ROUND($0xe1); \ 79 | ROUND($0xd2); \ 80 | ROUND($0xc3); \ 81 | ROUND($0xb4); \ 82 | ROUND($0xa5); \ 83 | ROUND($0x96); \ 84 | ROUND($0x87); \ 85 | ROUND($0x78); \ 86 | ROUND($0x69); \ 87 | ROUND($0x5a); \ 88 | ROUND($0x4b) 89 | 90 | #define P8 \ 91 | ROUND($0xb4); \ 92 | ROUND($0xa5); \ 93 | ROUND($0x96); \ 94 | ROUND($0x87); \ 95 | ROUND($0x78); \ 96 | ROUND($0x69); \ 97 | ROUND($0x5a); \ 98 | ROUND($0x4b) 99 | 100 | #define P6 \ 101 | ROUND($0x96); \ 102 | ROUND($0x87); \ 103 | ROUND($0x78); \ 104 | ROUND($0x69); \ 105 | ROUND($0x5a); \ 106 | ROUND($0x4b) 107 | 108 | // func p12(s *state) 109 | TEXT ·p12(SB), NOSPLIT, $0-8 110 | PERM_LOAD 111 | P12 112 | PERM_STORE 113 | RET 114 | 115 | // func p8(s *state) 116 | TEXT ·p8(SB), NOSPLIT, $0-8 117 | PERM_LOAD 118 | P8 119 | PERM_STORE 120 | RET 121 | 122 | // func p6(s *state) 123 | TEXT ·p6(SB), NOSPLIT, $0-8 124 | PERM_LOAD 125 | P6 126 | PERM_STORE 127 | RET 128 | 129 | // func round(s *state, C uint64) 130 | TEXT ·round(SB), NOSPLIT, $0-16 131 | PERM_LOAD 132 | MOVD C+8(FP), R11 133 | ROUND(R11) 134 | PERM_STORE 135 | RET 136 | 137 | // func additionalData128a(s *state, ad []byte) 138 | TEXT ·additionalData128a(SB), NOSPLIT, $0-32 139 | #define ad_ptr R11 140 | #define remain R12 141 | #define a0 R13 142 | #define a1 R14 143 | 144 | PERM_LOAD 145 | MOVD ad_base+8(FP), ad_ptr 146 | MOVD ad_len+16(FP), remain 147 | ADD $16, remain 148 | 149 | loop: 150 | LDP.P 16(ad_ptr), (a0, a1) 151 | SUB $16, remain 152 | CMP $16, remain 153 | REV a0, a0 154 | REV a1, a1 155 | EOR a0, s0, s0 156 | EOR a1, s1, s1 157 | P8 158 | BGT loop 159 | 160 | PERM_STORE 161 | RET 162 | 163 | #undef ad_ptr 164 | #undef remain 165 | #undef a0 166 | #undef a1 167 | 168 | // func encryptBlocks128a(s *state, dst, src []byte) 169 | TEXT ·encryptBlocks128a(SB), NOSPLIT, $0-56 170 | #define src_ptr R11 171 | #define dst_ptr R12 172 | #define remain R13 173 | #define c0 R14 174 | #define c1 R15 175 | 176 | PERM_LOAD 177 | MOVD dst_base+8(FP), dst_ptr 178 | MOVD src_base+32(FP), src_ptr 179 | MOVD src_len+40(FP), remain 180 | ADD $16, remain 181 | 182 | loop: 183 | LDP.P 16(src_ptr), (c0, c1) 184 | SUB $16, remain 185 | CMP $16, remain 186 | REV c0, c0 187 | REV c1, c1 188 | EOR c0, s0, s0 189 | EOR c1, s1, s1 190 | REV s0, c0 191 | REV s1, c1 192 | STP.P (c0, c1), 16(dst_ptr) 193 | P8 194 | BGT loop 195 | 196 | PERM_STORE 197 | RET 198 | 199 | #undef src_ptr 200 | #undef dst_ptr 201 | #undef remain 202 | #undef c0 203 | #undef c1 204 | 205 | // func decryptBlocks128a(s *state, dst, src []byte) 206 | TEXT ·decryptBlocks128a(SB), NOSPLIT, $0-56 207 | #define src_ptr R11 208 | #define dst_ptr R12 209 | #define remain R13 210 | #define c0 R14 211 | #define c1 R15 212 | 213 | PERM_LOAD 214 | MOVD dst_base+8(FP), dst_ptr 215 | MOVD src_base+32(FP), src_ptr 216 | MOVD src_len+40(FP), remain 217 | ADD $16, remain 218 | 219 | loop: 220 | LDP.P 16(src_ptr), (c0, c1) 221 | SUB $16, remain 222 | CMP $16, remain 223 | REV c0, c0 224 | REV c1, c1 225 | EOR c0, s0, s0 // clobber s0 226 | EOR c1, s1, s1 // clobber s1 227 | REV s0, s0 228 | REV s1, s1 229 | STP.P (s0, s1), 16(dst_ptr) 230 | MOVD c0, s0 // reassign s0 231 | MOVD c1, s1 // reassign s1 232 | P8 233 | BGT loop 234 | 235 | PERM_STORE 236 | RET 237 | 238 | #undef src_ptr 239 | #undef dst_ptr 240 | #undef remain 241 | #undef c0 242 | #undef c1 243 | -------------------------------------------------------------------------------- /grain/grain_test.go: -------------------------------------------------------------------------------- 1 | package grain 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "crypto/cipher" 7 | "encoding/hex" 8 | "fmt" 9 | "math" 10 | "math/rand" 11 | "os" 12 | "path/filepath" 13 | "strings" 14 | "testing" 15 | ) 16 | 17 | func TestKeystream(t *testing.T) { 18 | key := make([]byte, KeySize) 19 | nonce := make([]byte, NonceSize) 20 | for i := 0; i < 1_000; i++ { 21 | if _, err := rand.Read(key); err != nil { 22 | t.Fatal(err) 23 | } 24 | if _, err := rand.Read(nonce); err != nil { 25 | t.Fatal(err) 26 | } 27 | 28 | var g1 state 29 | g1.setKey(key) 30 | g1.init(nonce) 31 | 32 | var g2 state 33 | g2.setKey(key) 34 | g2.init(nonce) 35 | 36 | for j := 0; j < 10_000; j++ { 37 | v1 := nextGeneric(&g1) 38 | v2 := next(&g2) 39 | if v1 != v2 { 40 | t.Fatalf("#%d (#%d): expected %#x, got %#x", i, j, v1, v2) 41 | } 42 | } 43 | } 44 | } 45 | 46 | func TestAuth(t *testing.T) { 47 | key := make([]byte, KeySize) 48 | if _, err := rand.Read(key); err != nil { 49 | t.Fatal(err) 50 | } 51 | 52 | nonce := make([]byte, NonceSize) 53 | if _, err := rand.Read(nonce); err != nil { 54 | t.Fatal(err) 55 | } 56 | 57 | for i := 0; i < 100; i++ { 58 | var g1 state 59 | g1.setKey(key) 60 | g1.init(nonce) 61 | 62 | var g2 state 63 | g2.setKey(key) 64 | g2.init(nonce) 65 | 66 | for j := 0; j < math.MaxUint16; j++ { 67 | g1.reg, g1.acc = accumulateGeneric(g1.reg, g1.acc, uint16(i), uint16(j)) 68 | g2.reg, g2.acc = accumulate(g2.reg, g2.acc, uint16(i), uint16(j)) 69 | if g1.acc != g2.acc { 70 | t.Fatalf("#%d (#%d): expected %#x, got %#x", i, j, g1.acc, g2.acc) 71 | } 72 | if g1.reg != g2.reg { 73 | t.Fatalf("#%d (#%d): expected %#x, got %#x", i, j, g1.reg, g2.reg) 74 | } 75 | } 76 | } 77 | } 78 | 79 | func TestVectorsLE(t *testing.T) { 80 | testVectors(t, New, filepath.Join("testdata", "little_endian.txt")) 81 | } 82 | 83 | func testVectors(t *testing.T, fn func([]byte) (cipher.AEAD, error), path string) { 84 | vecs, err := readVecs(path) 85 | if err != nil { 86 | t.Fatal(err) 87 | } 88 | for i, v := range vecs { 89 | c, err := fn(v.key) 90 | if err != nil { 91 | t.Fatalf("#%d: %v", i+1, err) 92 | } 93 | ciphertext := c.Seal(nil, v.nonce, v.pt, v.ad) 94 | if !bytes.Equal(ciphertext, v.ct) { 95 | t.Fatalf("#%d: expected %#x, got %#x", i+1, v.ct, ciphertext) 96 | } 97 | plaintext, err := c.Open(nil, v.nonce, v.ct, v.ad) 98 | if err != nil { 99 | t.Fatalf("#%d: %v", i+1, err) 100 | } 101 | if !bytes.Equal(plaintext, v.pt) { 102 | t.Fatalf("#%d: expected %#x, got %#x", i+1, v.pt, plaintext) 103 | } 104 | } 105 | } 106 | 107 | var Sink32 uint32 108 | 109 | func BenchmarkKeystream(b *testing.B) { 110 | benchmarkKeystream(b, next) 111 | } 112 | 113 | func BenchmarkKeystreamGeneric(b *testing.B) { 114 | benchmarkKeystream(b, nextGeneric) 115 | } 116 | 117 | func benchmarkKeystream(b *testing.B, fn func(*state) uint32) { 118 | key := make([]byte, KeySize) 119 | if _, err := rand.Read(key); err != nil { 120 | b.Fatal(err) 121 | } 122 | nonce := make([]byte, NonceSize) 123 | if _, err := rand.Read(nonce); err != nil { 124 | b.Fatal(err) 125 | } 126 | 127 | var g state 128 | g.setKey(key) 129 | g.init(nonce) 130 | 131 | b.SetBytes(4) 132 | b.ResetTimer() 133 | 134 | for i := 0; i < b.N; i++ { 135 | Sink32 = fn(&g) 136 | } 137 | } 138 | 139 | func BenchmarkAuth(b *testing.B) { 140 | benchmarkAuth(b, accumulate) 141 | } 142 | 143 | func BenchmarkAuthGeneric(b *testing.B) { 144 | benchmarkAuth(b, accumulateGeneric) 145 | } 146 | 147 | func benchmarkAuth(b *testing.B, fn func(uint64, uint64, uint16, uint16) (uint64, uint64)) { 148 | key := make([]byte, KeySize) 149 | if _, err := rand.Read(key); err != nil { 150 | b.Fatal(err) 151 | } 152 | 153 | nonce := make([]byte, NonceSize) 154 | if _, err := rand.Read(nonce); err != nil { 155 | b.Fatal(err) 156 | } 157 | 158 | var g state 159 | g.setKey(key) 160 | g.init(nonce) 161 | 162 | b.SetBytes(2) 163 | b.ResetTimer() 164 | 165 | // FNV-1a 166 | const ( 167 | offset32 = 2166136261 168 | prime32 = 16777619 169 | ) 170 | pt := uint32(offset32) 171 | for i := 0; i < b.N; i++ { 172 | pt ^= uint32(i) 173 | pt *= prime32 174 | g.reg, g.acc = fn(g.reg, g.acc, uint16(i), uint16(pt)) 175 | } 176 | } 177 | 178 | func BenchmarkSeal1K(b *testing.B) { 179 | benchmarkSeal(b, New, make([]byte, 1024)) 180 | } 181 | 182 | func BenchmarkOpen1K(b *testing.B) { 183 | benchmarkOpen(b, New, make([]byte, 1024)) 184 | } 185 | 186 | func BenchmarkSeal8K(b *testing.B) { 187 | benchmarkSeal(b, New, make([]byte, 8*1024)) 188 | } 189 | 190 | func BenchmarkOpen8K(b *testing.B) { 191 | benchmarkOpen(b, New, make([]byte, 8*1024)) 192 | } 193 | 194 | func benchmarkSeal(b *testing.B, fn func([]byte) (cipher.AEAD, error), buf []byte) { 195 | b.SetBytes(int64(len(buf))) 196 | 197 | key := make([]byte, KeySize) 198 | nonce := make([]byte, NonceSize) 199 | ad := make([]byte, 13) 200 | aead, err := fn(key) 201 | if err != nil { 202 | b.Fatal(err) 203 | } 204 | var out []byte 205 | 206 | b.ResetTimer() 207 | for i := 0; i < b.N; i++ { 208 | out = aead.Seal(out[:0], nonce, buf, ad) 209 | } 210 | } 211 | 212 | func benchmarkOpen(b *testing.B, fn func([]byte) (cipher.AEAD, error), buf []byte) { 213 | b.SetBytes(int64(len(buf))) 214 | 215 | key := make([]byte, KeySize) 216 | nonce := make([]byte, NonceSize) 217 | ad := make([]byte, 13) 218 | aead, err := fn(key) 219 | if err != nil { 220 | b.Fatal(err) 221 | } 222 | var out []byte 223 | out = aead.Seal(out[:0], nonce, buf, ad) 224 | 225 | b.ResetTimer() 226 | for i := 0; i < b.N; i++ { 227 | _, err := aead.Open(buf[:0], nonce, out, ad) 228 | if err != nil { 229 | b.Errorf("#%d: Open: %v", i, err) 230 | } 231 | } 232 | } 233 | 234 | type vector struct { 235 | key []byte 236 | nonce []byte 237 | pt []byte 238 | ad []byte 239 | ct []byte 240 | } 241 | 242 | func (v *vector) set(field string, p []byte) bool { 243 | switch field { 244 | case "Key": 245 | v.key = p 246 | case "Nonce": 247 | v.nonce = p 248 | case "PT": 249 | v.pt = p 250 | case "AD": 251 | v.ad = p 252 | case "CT": 253 | v.ct = p 254 | default: 255 | return false 256 | } 257 | return true 258 | } 259 | 260 | func readVecs(path string) ([]vector, error) { 261 | f, err := os.Open(path) 262 | if err != nil { 263 | return nil, err 264 | } 265 | defer f.Close() 266 | 267 | var vecs []vector 268 | 269 | s := bufio.NewScanner(f) 270 | for i := 0; s.Scan(); i++ { 271 | t := s.Text() 272 | if t == "" { 273 | continue 274 | } 275 | if strings.HasPrefix(t, "Count = ") { 276 | vecs = append(vecs, vector{}) 277 | continue 278 | } 279 | i := strings.IndexByte(t, '=') 280 | if i < 0 { 281 | return nil, fmt.Errorf("malformed line %d: %q", i+1, t) 282 | } 283 | data := strings.TrimSpace(t[i+1:]) 284 | buf, err := hex.DecodeString(data) 285 | if err != nil { 286 | return nil, fmt.Errorf("malformed line %d: %v", i+1, err) 287 | } 288 | field := strings.TrimSpace(t[:i]) 289 | if !vecs[len(vecs)-1].set(field, buf) { 290 | return nil, fmt.Errorf("malformed line %d: %q", i+1, t) 291 | } 292 | } 293 | return vecs, nil 294 | } 295 | -------------------------------------------------------------------------------- /grain/asm/asm.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | 8 | . "github.com/mmcloughlin/avo/build" 9 | . "github.com/mmcloughlin/avo/gotypes" 10 | . "github.com/mmcloughlin/avo/operand" 11 | . "github.com/mmcloughlin/avo/reg" 12 | ) 13 | 14 | //go:generate go run asm.go -out ../grain_amd64.s -stubs ../stub_amd64.go -pkg grain 15 | 16 | func main() { 17 | Package("github.com/ericlagergren/lwcrypto/grain") 18 | ConstraintExpr("gc,!purego") 19 | 20 | declareKeystream() 21 | declareAccumulate() 22 | 23 | Generate() 24 | } 25 | 26 | type state struct { 27 | s Component // *state 28 | acc Component // uint64 29 | reg Component // uint64 30 | } 31 | 32 | // loadState dereferences the *state in p and loads it into r. 33 | func loadState(p Component, r Register) state { 34 | Comment("Load state") 35 | if _, err := p.Resolve(); err != nil { 36 | panic(err) 37 | } 38 | Load(p, r) 39 | s := p.Dereference(r) 40 | return state{ 41 | s: s, 42 | acc: s.Field("acc"), 43 | reg: s.Field("reg"), 44 | } 45 | } 46 | 47 | func (s state) store(l lfsr) { 48 | Commentf("Store %s: (lo, hi)", l.name) 49 | Store(l.lo, s.s.Field(l.name).Field("lo")) 50 | Store(l.hi, s.s.Field(l.name).Field("hi")) 51 | } 52 | 53 | func (s state) load(name string) lfsr { 54 | Commentf("Load %s: (lo, hi)", name) 55 | return lfsr{ 56 | name: name, 57 | lo: Load(s.s.Field(name).Field("lo"), GP64()), 58 | hi: Load(s.s.Field(name).Field("hi"), GP64()), 59 | } 60 | } 61 | 62 | func (s state) lfsr() lfsr { return s.load("lfsr") } 63 | func (s state) nfsr() lfsr { return s.load("nfsr") } 64 | 65 | func declareKeystream() { 66 | TEXT("next", NOSPLIT, "func(s *state) uint32") 67 | Pragma("noescape") 68 | 69 | s := loadState(Param("s"), GP64()) 70 | 71 | Comment("LFSR shifts") 72 | lfsr := s.lfsr() 73 | ln0 := named(GP64(), "ln0") 74 | ln1 := named(GP64(), "ln1") 75 | ln2 := named(GP64(), "ln2") 76 | ln3 := named(GP64(), "ln3") 77 | lfsr.words(ln0, ln1, ln2, ln3) 78 | 79 | t := named(GP64(), "") 80 | v := named(GP64(), "v") 81 | 82 | // v := ln0 ^ ln3 83 | Comment("v := ln ^ ln3") 84 | MOVQ(ln0, v) 85 | XORQ(ln3, v) 86 | 87 | // No longer used 88 | ln3 = nil 89 | 90 | // v ^= (ln1 ^ ln2) >> 6 91 | Comment(" = ln1 ^ ln2") 92 | MOVQ(ln1, t) 93 | XORQ(ln2, t) 94 | shiftrAndXor(v, t, 6) 95 | 96 | // v ^= ln0 >> 7 97 | shiftrAndXor(v, ln0, 7) 98 | // v ^= ln2 >> 17 99 | shiftrAndXor(v, ln2, 17) 100 | 101 | // Update LFSR. 102 | lfsr.shift(v) 103 | s.store(lfsr) 104 | 105 | Comment("NFSR shifts") 106 | nfsr := s.nfsr() 107 | nn0 := named(GP64(), "nn0") 108 | nn1 := named(GP64(), "nn1") 109 | nn2 := named(GP64(), "nn2") 110 | nn3 := named(GP64(), "nn3") 111 | nfsr.words(nn0, nn1, nn2, nn3) 112 | 113 | u := named(v, "u") 114 | v = nil 115 | 116 | // u := ln0 117 | Comment("u := ln0") 118 | MOVQ(ln0, u) 119 | // u ^= nn0 120 | Comment("u ^= nn0") 121 | XORQ(nn0, u) 122 | // u ^= nn0 >> 26 123 | shiftrAndXor(u, nn0, 26) 124 | // u ^= nn3 125 | XORQ(nn3, u) 126 | // u ^= nn1 >> 24 127 | shiftrAndXor(u, nn1, 24) 128 | 129 | // u ^= ((nn0 & nn1) ^ nn2) >> 27 130 | Comment(" = (nn0 & nn2) ^ nn2") 131 | MOVQ(nn1, t) 132 | ANDQ(nn0, t) 133 | XORQ(nn2, t) 134 | shiftrAndXor(u, t, 27) 135 | 136 | // u ^= (nn0 & nn2) >> 3 137 | Comment(" = nn0 & nn2") 138 | MOVQ(nn2, t) 139 | ANDQ(nn0, t) 140 | shiftrAndXor(u, t, 3) 141 | 142 | // u ^= (nn0 >> 11) & (nn0 >> 13) 143 | shiftrAndXor(u, nn0, 11, nn0, 13) 144 | // u ^= (nn0 >> 17) & (nn0 >> 18) 145 | shiftrAndXor(u, nn0, 17, nn0, 18) 146 | // u ^= (nn1 >> 8) & (nn1 >> 16) 147 | shiftrAndXor(u, nn1, 8, nn1, 16) 148 | // u ^= (nn1 >> 29) & (nn2 >> 1) 149 | shiftrAndXor(u, nn1, 29, nn2, 1) 150 | // u ^= (nn2 >> 4) & (nn2 >> 20) 151 | shiftrAndXor(u, nn2, 4, nn2, 20) 152 | // u ^= (nn2 >> 24) & (nn2 >> 28) & (nn2 >> 29) & (nn2 >> 31) 153 | shiftrAndXor(u, nn2, 24, nn2, 28, nn2, 29, nn2, 31) 154 | // u ^= (nn0 >> 22) & (nn0 >> 24) & (nn0 >> 25) 155 | shiftrAndXor(u, nn0, 22, nn0, 24, nn0, 25) 156 | // u ^= (nn2 >> 6) & (nn2 >> 14) & (nn2 >> 18) 157 | shiftrAndXor(u, nn2, 6, nn2, 14, nn2, 18) 158 | 159 | // Update NFSR. 160 | nfsr.shift(u) 161 | s.store(nfsr) 162 | 163 | x := named(u, "x") 164 | u = nil 165 | 166 | // x := nn0 >> 2 167 | shrq3(x, nn0, 2) 168 | // x ^= nn0 >> 15 169 | shiftrAndXor(x, nn0, 15) 170 | // x ^= nn1 >> 4 171 | shiftrAndXor(x, nn1, 4) 172 | // x ^= nn1 >> 13 173 | shiftrAndXor(x, nn1, 13) 174 | // x ^= nn2 175 | XORQ(nn2, x) 176 | // x ^= nn2 >> 9 177 | shiftrAndXor(x, nn2, 9) 178 | // x ^= nn2 >> 25 179 | shiftrAndXor(x, nn2, 25) 180 | // x ^= ln2 >> 29 181 | shiftrAndXor(x, ln2, 29) 182 | // x ^= (nn0 >> 12) & (ln0 >> 8) 183 | shiftrAndXor(x, nn0, 12, ln0, 8) 184 | // x ^= (ln0 >> 13) & (ln0 >> 20) 185 | shiftrAndXor(x, ln0, 13, ln0, 20) 186 | // x ^= (nn2 >> 31) & (ln1 >> 10) 187 | shiftrAndXor(x, nn2, 31, ln1, 10) 188 | // x ^= (ln1 >> 28) & (ln2 >> 15) 189 | shiftrAndXor(x, ln1, 28, ln2, 15) 190 | // x ^= (nn0 >> 12) & (nn2 >> 31) & (ln2 >> 30) 191 | shiftrAndXor(x, nn0, 12, nn2, 31, ln2, 30) 192 | 193 | Comment("Store result") 194 | Store(x.As32(), ReturnIndex(0)) 195 | 196 | RET() 197 | } 198 | 199 | type lfsr struct { 200 | name string 201 | lo, hi Register 202 | } 203 | 204 | func (l lfsr) words(u0, u1, u2, u3 GPVirtual) { 205 | Comment("Load " + l.name + " words (u0, u1, u2, u3)") 206 | t := GP64() 207 | 208 | Comment("u0 = r.lo") 209 | MOVQ(l.lo, u0) 210 | 211 | Comment("u1 = r.lo>>32 | r.hi<<32") 212 | MOVQ(l.lo, u1) 213 | shrq(32, u1) 214 | MOVQ(l.hi, t) 215 | shlq(32, t) 216 | ORQ(t, u1) 217 | 218 | Comment("u2 = r.hi") 219 | MOVQ(l.hi, u2) 220 | 221 | Comment("u3 = r.hi>>32") 222 | MOVQ(l.hi, u3) 223 | shrq(32, u3) 224 | } 225 | 226 | // shift shifts off 32 low bits and replaces the high bits with 227 | // x: 228 | // 229 | // u = (u >> 32) | (x << 96) 230 | // 231 | func (l lfsr) shift(x Register) { 232 | t := GP64() 233 | 234 | Comment("lo = r.lo>>32 | r.hi<<(64-32)") 235 | shrq(32, l.lo) 236 | MOVQ(l.hi, t) 237 | shlq(32, t) 238 | ORQ(t, l.lo) 239 | 240 | Comment("r.hi>>32 | uint64(x)<<32") 241 | shrq(32, l.hi) 242 | MOVQ(x, t) 243 | shlq(32, t) 244 | ORQ(t, l.hi) 245 | } 246 | 247 | func declareAccumulate() { 248 | TEXT("accumulate", NOSPLIT, "func(reg, acc uint64, ms, pt uint16) (reg1, acc1 uint64)") 249 | Pragma("noescape") 250 | 251 | reg := Load(Param("reg"), GP64()) 252 | acc := Load(Param("acc"), GP64()) 253 | pt := Load(Param("pt"), GP32()) 254 | ms := Load(Param("ms"), GP64()).(GPVirtual) 255 | 256 | Comment("var acctmp uint16") 257 | acctmp := GP64() 258 | XORQ(acctmp, acctmp) 259 | 260 | Comment("regtmp := uint32(ms) << 16") 261 | regtmp := GP32() 262 | MOVWLZX(ms.As16(), regtmp) 263 | shll(16, regtmp) 264 | 265 | mask := GP64() 266 | tmp := GP64() 267 | for i := 0; i < 16; i++ { 268 | Comment("mask := -uint64(pt & 1)") 269 | MOVL(pt, mask.As32()) 270 | ANDL(U8(1), mask.As32()) 271 | NEGQ(mask) 272 | 273 | Comment("acc ^= reg & mask") 274 | MOVQ(reg, tmp) 275 | ANDQ(mask, tmp) 276 | XORQ(tmp, acc) 277 | 278 | Comment("acctmp ^= uint16(regtmp) & uint16(mask)") 279 | ANDW(regtmp.As16(), mask.As16()) // clobber mask 280 | XORW(mask.As16(), acctmp.As16()) 281 | 282 | Comment("reg >>= 1") 283 | shrq(1, reg) 284 | 285 | Comment("pt >>= 1") 286 | shrl(1, pt) 287 | 288 | // Last iteration does not matter. 289 | if i < 15 { 290 | Comment("regtmp >>= 1") 291 | SHRL(U8(1), regtmp) 292 | } 293 | } 294 | 295 | Comment("reg |= uint64(ms) << 48") // 1 296 | Comment("acc ^= uint64(acctmp) << 48") // 2 297 | 298 | shlq(48, ms) // 1 299 | shlq(48, acctmp) // 2 300 | ORQ(ms, reg) // 1 301 | XORQ(acctmp, acc) // 2 302 | 303 | Comment("Store results") 304 | Store(reg, ReturnIndex(0)) 305 | Store(acc, ReturnIndex(1)) 306 | 307 | RET() 308 | } 309 | 310 | // addr returns the address of the Component, or panics. 311 | func addr(c Component) Mem { 312 | b, err := c.Resolve() 313 | if err != nil { 314 | panic(err) 315 | } 316 | return b.Addr 317 | } 318 | 319 | func shrq(x uint8, op Op) { SHRQ(U8(x), op) } 320 | func shrl(x uint8, op Op) { SHRL(U8(x), op) } 321 | func shlq(x uint8, op Op) { SHLQ(U8(x), op) } 322 | func shll(x uint8, op Op) { SHLL(U8(x), op) } 323 | 324 | // shrq3 performs 325 | // t = o >> s 326 | func shrq3(t, o Op, s uint8) { 327 | MOVQ(o, t) 328 | shrq(s, t) 329 | } 330 | 331 | // shiftrAndXor performs 332 | // z ^= (a >> b) & (c >> d) & ... 333 | func shiftrAndXor(z Register, args ...interface{}) { 334 | if len(args)%2 != 0 || len(args) < 2 { 335 | panic("invalid number of arguments: " + strconv.Itoa(len(args))) 336 | } 337 | 338 | var b strings.Builder 339 | fmt.Fprintf(&b, "%s ^= ", z) 340 | for i := 0; i < len(args); i += 2 { 341 | if i > 0 { 342 | b.WriteString(" & ") 343 | } 344 | fmt.Fprintf(&b, "(%s >> %d)", args[i], args[i+1]) 345 | } 346 | Comment(b.String()) 347 | 348 | next := func() (uint8, Op) { 349 | o := args[0].(Op) 350 | s := args[1].(int) 351 | if s < 0 || s > 64 { 352 | panic("shift out of range: " + strconv.Itoa(s)) 353 | } 354 | args = args[2:] 355 | return uint8(s), o 356 | } 357 | 358 | t := GP64() 359 | s, o := next() 360 | shrq3(t, o, s) 361 | 362 | var t2 Register 363 | for len(args) > 0 { 364 | if t2 == nil { 365 | t2 = GP64() 366 | } 367 | s, o := next() 368 | shrq3(t2, o, s) 369 | ANDQ(t2, t) 370 | } 371 | 372 | XORQ(t, z) 373 | } 374 | 375 | func named(r GPVirtual, name string) GPVirtual { 376 | return namedRegister{r, name} 377 | } 378 | 379 | type namedRegister struct { 380 | GPVirtual 381 | name string 382 | } 383 | 384 | func (n namedRegister) String() string { 385 | return n.name 386 | } 387 | -------------------------------------------------------------------------------- /ascon/ascon.go: -------------------------------------------------------------------------------- 1 | // Package ascon implements the ASCON AEAD cipher. 2 | // 3 | // References: 4 | // 5 | // [ascon]: https://ascon.iaik.tugraz.at 6 | // 7 | package ascon 8 | 9 | import ( 10 | "crypto/cipher" 11 | "encoding/binary" 12 | "errors" 13 | "runtime" 14 | "strconv" 15 | 16 | "github.com/ericlagergren/subtle" 17 | ) 18 | 19 | //go:generate go run github.com/ericlagergren/lwcrypto/ascon/internal/cmd/pgen 20 | 21 | var errOpen = errors.New("ascon: message authentication failed") 22 | 23 | const ( 24 | // BlockSize128a is the size in bytes of an ASCON-128a block. 25 | BlockSize128a = 16 26 | // BlockSize128 is the size in bytes of an ASCON-128 block. 27 | BlockSize128 = 8 28 | // KeySize is the size in bytes of ASCON-128 and ASCON-128a 29 | // keys. 30 | KeySize = 16 31 | // NonceSize is the size in bytes of ASCON-128 and ASCON-128a 32 | // nonces. 33 | NonceSize = 16 34 | // TagSize is the size in bytes of ASCON-128 and ASCON-128a 35 | // authenticators. 36 | TagSize = 16 37 | ) 38 | 39 | type ascon struct { 40 | k0, k1 uint64 41 | iv uint64 42 | } 43 | 44 | var _ cipher.AEAD = (*ascon)(nil) 45 | 46 | // New128 creates a 128-bit ASCON-128 AEAD. 47 | // 48 | // ASCON-128 provides lower throughput but increased robustness 49 | // against partial or full state recovery compared to ASCON-128a. 50 | // 51 | // Each unique key can encrypt a maximum 2^68 bytes (i.e., 2^64 52 | // plaintext and associated data blocks). Nonces must never be 53 | // reused with the same key. Violating either of these 54 | // constraints compromises the security of the algorithm. 55 | // 56 | // There are no other constraints on the composition of the 57 | // nonce. For example, the nonce can be a counter. 58 | // 59 | // Refer to ASCON's documentation for more information. 60 | func New128(key []byte) (cipher.AEAD, error) { 61 | if len(key) != KeySize { 62 | return nil, errors.New("ascon: bad key length") 63 | } 64 | return &ascon{ 65 | k0: binary.BigEndian.Uint64(key[0:8]), 66 | k1: binary.BigEndian.Uint64(key[8:16]), 67 | iv: iv128, 68 | }, nil 69 | } 70 | 71 | // New128a creates a 128-bit ASCON-128a AEAD. 72 | // 73 | // ASCON-128a provides higher throughput but reduced robustness 74 | // against partial or full state recovery compared to ASCON-128. 75 | // 76 | // Each unique key can encrypt a maximum 2^68 bytes (i.e., 2^64 77 | // plaintext and associated data blocks). Nonces must never be 78 | // reused with the same key. Violating either of these 79 | // constraints compromises the security of the algorithm. 80 | // 81 | // There are no other constraints on the composition of the 82 | // nonce. For example, the nonce can be a counter. 83 | // 84 | // Refer to ASCON's documentation for more information. 85 | func New128a(key []byte) (cipher.AEAD, error) { 86 | if len(key) != KeySize { 87 | return nil, errors.New("ascon: bad key length") 88 | } 89 | return &ascon{ 90 | k0: binary.BigEndian.Uint64(key[0:8]), 91 | k1: binary.BigEndian.Uint64(key[8:16]), 92 | iv: iv128a, 93 | }, nil 94 | } 95 | 96 | func (a *ascon) NonceSize() int { 97 | return NonceSize 98 | } 99 | 100 | func (a *ascon) Overhead() int { 101 | return TagSize 102 | } 103 | 104 | func (a *ascon) Seal(dst, nonce, plaintext, additionalData []byte) []byte { 105 | if len(nonce) != NonceSize { 106 | panic("ascon: incorrect nonce length: " + strconv.Itoa(len(nonce))) 107 | } 108 | // TODO(eric): ciphertext max length? 109 | 110 | n0 := binary.BigEndian.Uint64(nonce[0:8]) 111 | n1 := binary.BigEndian.Uint64(nonce[8:16]) 112 | 113 | var s state 114 | s.init(a.iv, a.k0, a.k1, n0, n1) 115 | 116 | if a.iv == iv128a { 117 | s.additionalData128a(additionalData) 118 | } else { 119 | s.additionalData128(additionalData) 120 | } 121 | 122 | ret, out := subtle.SliceForAppend(dst, len(plaintext)+TagSize) 123 | if subtle.InexactOverlap(out, plaintext) { 124 | panic("ascon: invalid buffer overlap") 125 | } 126 | if a.iv == iv128a { 127 | s.encrypt128a(out[:len(plaintext)], plaintext) 128 | } else { 129 | s.encrypt128(out[:len(plaintext)], plaintext) 130 | } 131 | 132 | if a.iv == iv128a { 133 | s.finalize128a(a.k0, a.k1) 134 | } else { 135 | s.finalize128(a.k0, a.k1) 136 | } 137 | s.tag(out[len(out)-TagSize:]) 138 | 139 | return ret 140 | } 141 | 142 | func (a *ascon) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { 143 | if len(nonce) != NonceSize { 144 | panic("ascon: incorrect nonce length: " + strconv.Itoa(len(nonce))) 145 | } 146 | if len(ciphertext) < TagSize { 147 | return nil, errOpen 148 | } 149 | // TODO(eric): ciphertext max length? 150 | 151 | tag := ciphertext[len(ciphertext)-TagSize:] 152 | ciphertext = ciphertext[:len(ciphertext)-TagSize] 153 | 154 | n0 := binary.BigEndian.Uint64(nonce[0:8]) 155 | n1 := binary.BigEndian.Uint64(nonce[8:16]) 156 | 157 | var s state 158 | s.init(a.iv, a.k0, a.k1, n0, n1) 159 | 160 | if a.iv == iv128a { 161 | s.additionalData128a(additionalData) 162 | } else { 163 | s.additionalData128(additionalData) 164 | } 165 | 166 | ret, out := subtle.SliceForAppend(dst, len(ciphertext)) 167 | if subtle.InexactOverlap(out, ciphertext) { 168 | panic("ascon: invalid buffer overlap") 169 | } 170 | if a.iv == iv128a { 171 | s.decrypt128a(out, ciphertext) 172 | } else { 173 | s.decrypt128(out, ciphertext) 174 | } 175 | 176 | if a.iv == iv128a { 177 | s.finalize128a(a.k0, a.k1) 178 | } else { 179 | s.finalize128(a.k0, a.k1) 180 | } 181 | 182 | expectedTag := make([]byte, TagSize) 183 | s.tag(expectedTag) 184 | 185 | if subtle.ConstantTimeCompare(expectedTag, tag) != 1 { 186 | for i := range out { 187 | out[i] = 0 188 | } 189 | runtime.KeepAlive(out) 190 | return nil, errOpen 191 | } 192 | return ret, nil 193 | } 194 | 195 | const ( 196 | iv128 uint64 = 0x80400c0600000000 // Ascon-128 197 | iv128a uint64 = 0x80800c0800000000 // Ascon-128a 198 | ) 199 | 200 | type state struct { 201 | x0, x1, x2, x3, x4 uint64 202 | } 203 | 204 | func (s *state) init(iv, k0, k1, n0, n1 uint64) { 205 | s.x0 = iv 206 | s.x1 = k0 207 | s.x2 = k1 208 | s.x3 = n0 209 | s.x4 = n1 210 | p12(s) 211 | s.x3 ^= k0 212 | s.x4 ^= k1 213 | } 214 | 215 | func (s *state) finalize128a(k0, k1 uint64) { 216 | s.x2 ^= k0 217 | s.x3 ^= k1 218 | p12(s) 219 | s.x3 ^= k0 220 | s.x4 ^= k1 221 | } 222 | 223 | func (s *state) additionalData128a(ad []byte) { 224 | if len(ad) > 0 { 225 | n := len(ad) &^ (BlockSize128a - 1) 226 | if n > 0 { 227 | additionalData128a(s, ad[:n]) 228 | ad = ad[n:] 229 | } 230 | if len(ad) >= 8 { 231 | s.x0 ^= binary.BigEndian.Uint64(ad[0:8]) 232 | s.x1 ^= be64n(ad[8:]) 233 | s.x1 ^= pad(len(ad) - 8) 234 | } else { 235 | s.x0 ^= be64n(ad) 236 | s.x0 ^= pad(len(ad)) 237 | } 238 | p8(s) 239 | } 240 | s.x4 ^= 1 241 | } 242 | 243 | func (s *state) encrypt128a(dst, src []byte) { 244 | n := len(src) &^ (BlockSize128a - 1) 245 | if n > 0 { 246 | encryptBlocks128a(s, dst[:n], src[:n]) 247 | src = src[n:] 248 | dst = dst[n:] 249 | } 250 | if len(src) >= 8 { 251 | s.x0 ^= binary.BigEndian.Uint64(src[0:8]) 252 | s.x1 ^= be64n(src[8:]) 253 | s.x1 ^= pad(len(src) - 8) 254 | binary.BigEndian.PutUint64(dst[0:8], s.x0) 255 | put64n(dst[8:], s.x1) 256 | } else { 257 | s.x0 ^= be64n(src) 258 | put64n(dst, s.x0) 259 | s.x0 ^= pad(len(src)) 260 | } 261 | } 262 | 263 | func (s *state) decrypt128a(dst, src []byte) { 264 | n := len(src) &^ (BlockSize128a - 1) 265 | if n > 0 { 266 | decryptBlocks128a(s, dst[:n], src[:n]) 267 | src = src[n:] 268 | dst = dst[n:] 269 | } 270 | if len(src) >= 8 { 271 | c0 := binary.BigEndian.Uint64(src[0:8]) 272 | c1 := be64n(src[8:]) 273 | binary.BigEndian.PutUint64(dst[0:8], s.x0^c0) 274 | put64n(dst[8:], s.x1^c1) 275 | s.x0 = c0 276 | s.x1 = mask(s.x1, len(src)-8) 277 | s.x1 |= c1 278 | s.x1 ^= pad(len(src) - 8) 279 | } else { 280 | c0 := be64n(src) 281 | put64n(dst, s.x0^c0) 282 | s.x0 = mask(s.x0, len(src)) 283 | s.x0 |= c0 284 | s.x0 ^= pad(len(src)) 285 | } 286 | } 287 | 288 | func (s *state) finalize128(k0, k1 uint64) { 289 | s.x1 ^= k0 290 | s.x2 ^= k1 291 | p12(s) 292 | s.x3 ^= k0 293 | s.x4 ^= k1 294 | } 295 | 296 | func (s *state) additionalData128(ad []byte) { 297 | if len(ad) > 0 { 298 | for len(ad) >= BlockSize128 { 299 | s.x0 ^= binary.BigEndian.Uint64(ad[0:8]) 300 | p6(s) 301 | ad = ad[BlockSize128:] 302 | } 303 | s.x0 ^= be64n(ad) 304 | s.x0 ^= pad(len(ad)) 305 | p6(s) 306 | } 307 | s.x4 ^= 1 308 | } 309 | 310 | func (s *state) encrypt128(dst, src []byte) { 311 | for len(src) >= BlockSize128 && len(dst) >= BlockSize128 { 312 | s.x0 ^= binary.BigEndian.Uint64(src[0:8]) 313 | binary.BigEndian.PutUint64(dst[0:8], s.x0) 314 | p6(s) 315 | src = src[BlockSize128:] 316 | dst = dst[BlockSize128:] 317 | } 318 | s.x0 ^= be64n(src) 319 | put64n(dst, s.x0) 320 | s.x0 ^= pad(len(src)) 321 | } 322 | 323 | func (s *state) decrypt128(dst, src []byte) { 324 | for len(src) >= BlockSize128 && len(dst) >= BlockSize128 { 325 | c := binary.BigEndian.Uint64(src[0:8]) 326 | binary.BigEndian.PutUint64(dst[0:8], s.x0^c) 327 | s.x0 = c 328 | p6(s) 329 | src = src[BlockSize128:] 330 | dst = dst[BlockSize128:] 331 | } 332 | c := be64n(src) 333 | put64n(dst, s.x0^c) 334 | s.x0 = mask(s.x0, len(src)) 335 | s.x0 |= c 336 | s.x0 ^= pad(len(src)) 337 | } 338 | 339 | func (s *state) tag(dst []byte) { 340 | binary.BigEndian.PutUint64(dst[0:8], s.x3) 341 | binary.BigEndian.PutUint64(dst[8:16], s.x4) 342 | } 343 | 344 | func pad(n int) uint64 { 345 | return 0x80 << (56 - 8*n) 346 | } 347 | 348 | func be64n(b []byte) uint64 { 349 | var x uint64 350 | for i := len(b) - 1; i >= 0; i-- { 351 | x |= uint64(b[i]) << (56 - i*8) 352 | } 353 | return x 354 | } 355 | 356 | func put64n(b []byte, x uint64) { 357 | for i := len(b) - 1; i >= 0; i-- { 358 | b[i] = byte(x >> (56 - 8*i)) 359 | } 360 | } 361 | 362 | func mask(x uint64, n int) uint64 { 363 | for i := 0; i < n; i++ { 364 | x &^= 255 << (56 - 8*i) 365 | } 366 | return x 367 | } 368 | -------------------------------------------------------------------------------- /ascon/zascon_generic.go: -------------------------------------------------------------------------------- 1 | // Code generated by pgen.go. DO NOT EDIT. 2 | 3 | package ascon 4 | 5 | import ( 6 | "encoding/binary" 7 | "math/bits" 8 | ) 9 | 10 | func additionalData128aGeneric(s *state, ad []byte) { 11 | s0 := s.x0 12 | s1 := s.x1 13 | s2 := s.x2 14 | s3 := s.x3 15 | s4 := s.x4 16 | for len(ad) >= BlockSize128a { 17 | s0 ^= binary.BigEndian.Uint64(ad[0:8]) 18 | s1 ^= binary.BigEndian.Uint64(ad[8:16]) 19 | for C := uint64(180); C >= 74; C -= 15 { 20 | // Round constant 21 | s2 ^= C 22 | 23 | // Substitution 24 | s0 ^= s4 25 | s4 ^= s3 26 | s2 ^= s1 27 | 28 | // Keccak S-box 29 | t0 := s0 ^ (^s1 & s2) 30 | t1 := s1 ^ (^s2 & s3) 31 | t2 := s2 ^ (^s3 & s4) 32 | t3 := s3 ^ (^s4 & s0) 33 | t4 := s4 ^ (^s0 & s1) 34 | 35 | // Substitution 36 | t1 ^= t0 37 | t0 ^= t4 38 | t3 ^= t2 39 | t2 = ^t2 40 | 41 | // Linear diffusion 42 | // 43 | // x0 ← Σ0(x0) = x0 ⊕ (x0 ≫ 19) ⊕ (x0 ≫ 28) 44 | s0 = t0 ^ bits.RotateLeft64(t0, -19) ^ bits.RotateLeft64(t0, -28) 45 | // x1 ← Σ1(x1) = x1 ⊕ (x1 ≫ 61) ⊕ (x1 ≫ 39) 46 | s1 = t1 ^ bits.RotateLeft64(t1, -61) ^ bits.RotateLeft64(t1, -39) 47 | // x2 ← Σ2(x2) = x2 ⊕ (x2 ≫ 1) ⊕ (x2 ≫ 6) 48 | s2 = t2 ^ bits.RotateLeft64(t2, -1) ^ bits.RotateLeft64(t2, -6) 49 | // x3 ← Σ3(x3) = x3 ⊕ (x3 ≫ 10) ⊕ (x3 ≫ 17) 50 | s3 = t3 ^ bits.RotateLeft64(t3, -10) ^ bits.RotateLeft64(t3, -17) 51 | // x4 ← Σ4(x4) = x4 ⊕ (x4 ≫ 7) ⊕ (x4 ≫ 41) 52 | s4 = t4 ^ bits.RotateLeft64(t4, -7) ^ bits.RotateLeft64(t4, -41) 53 | } 54 | ad = ad[BlockSize128a:] 55 | } 56 | s.x0 = s0 57 | s.x1 = s1 58 | s.x2 = s2 59 | s.x3 = s3 60 | s.x4 = s4 61 | } 62 | 63 | func encryptBlocks128aGeneric(s *state, dst, src []byte) { 64 | s0 := s.x0 65 | s1 := s.x1 66 | s2 := s.x2 67 | s3 := s.x3 68 | s4 := s.x4 69 | for len(src) >= BlockSize128a && len(dst) >= BlockSize128a { 70 | s0 ^= binary.BigEndian.Uint64(src[0:8]) 71 | s1 ^= binary.BigEndian.Uint64(src[8:16]) 72 | binary.BigEndian.PutUint64(dst[0:8], s0) 73 | binary.BigEndian.PutUint64(dst[8:16], s1) 74 | for C := uint64(180); C >= 74; C -= 15 { 75 | // Round constant 76 | s2 ^= C 77 | 78 | // Substitution 79 | s0 ^= s4 80 | s4 ^= s3 81 | s2 ^= s1 82 | 83 | // Keccak S-box 84 | t0 := s0 ^ (^s1 & s2) 85 | t1 := s1 ^ (^s2 & s3) 86 | t2 := s2 ^ (^s3 & s4) 87 | t3 := s3 ^ (^s4 & s0) 88 | t4 := s4 ^ (^s0 & s1) 89 | 90 | // Substitution 91 | t1 ^= t0 92 | t0 ^= t4 93 | t3 ^= t2 94 | t2 = ^t2 95 | 96 | // Linear diffusion 97 | // 98 | // x0 ← Σ0(x0) = x0 ⊕ (x0 ≫ 19) ⊕ (x0 ≫ 28) 99 | s0 = t0 ^ bits.RotateLeft64(t0, -19) ^ bits.RotateLeft64(t0, -28) 100 | // x1 ← Σ1(x1) = x1 ⊕ (x1 ≫ 61) ⊕ (x1 ≫ 39) 101 | s1 = t1 ^ bits.RotateLeft64(t1, -61) ^ bits.RotateLeft64(t1, -39) 102 | // x2 ← Σ2(x2) = x2 ⊕ (x2 ≫ 1) ⊕ (x2 ≫ 6) 103 | s2 = t2 ^ bits.RotateLeft64(t2, -1) ^ bits.RotateLeft64(t2, -6) 104 | // x3 ← Σ3(x3) = x3 ⊕ (x3 ≫ 10) ⊕ (x3 ≫ 17) 105 | s3 = t3 ^ bits.RotateLeft64(t3, -10) ^ bits.RotateLeft64(t3, -17) 106 | // x4 ← Σ4(x4) = x4 ⊕ (x4 ≫ 7) ⊕ (x4 ≫ 41) 107 | s4 = t4 ^ bits.RotateLeft64(t4, -7) ^ bits.RotateLeft64(t4, -41) 108 | } 109 | src = src[BlockSize128a:] 110 | dst = dst[BlockSize128a:] 111 | } 112 | s.x0 = s0 113 | s.x1 = s1 114 | s.x2 = s2 115 | s.x3 = s3 116 | s.x4 = s4 117 | } 118 | 119 | func decryptBlocks128aGeneric(s *state, dst, src []byte) { 120 | s0 := s.x0 121 | s1 := s.x1 122 | s2 := s.x2 123 | s3 := s.x3 124 | s4 := s.x4 125 | for len(src) >= BlockSize128a && len(dst) >= BlockSize128a { 126 | c0 := binary.BigEndian.Uint64(src[0:8]) 127 | c1 := binary.BigEndian.Uint64(src[8:16]) 128 | binary.BigEndian.PutUint64(dst[0:8], s0^c0) 129 | binary.BigEndian.PutUint64(dst[8:16], s1^c1) 130 | s0, s1 = c0, c1 131 | for C := uint64(180); C >= 74; C -= 15 { 132 | // Round constant 133 | s2 ^= C 134 | 135 | // Substitution 136 | s0 ^= s4 137 | s4 ^= s3 138 | s2 ^= s1 139 | 140 | // Keccak S-box 141 | t0 := s0 ^ (^s1 & s2) 142 | t1 := s1 ^ (^s2 & s3) 143 | t2 := s2 ^ (^s3 & s4) 144 | t3 := s3 ^ (^s4 & s0) 145 | t4 := s4 ^ (^s0 & s1) 146 | 147 | // Substitution 148 | t1 ^= t0 149 | t0 ^= t4 150 | t3 ^= t2 151 | t2 = ^t2 152 | 153 | // Linear diffusion 154 | // 155 | // x0 ← Σ0(x0) = x0 ⊕ (x0 ≫ 19) ⊕ (x0 ≫ 28) 156 | s0 = t0 ^ bits.RotateLeft64(t0, -19) ^ bits.RotateLeft64(t0, -28) 157 | // x1 ← Σ1(x1) = x1 ⊕ (x1 ≫ 61) ⊕ (x1 ≫ 39) 158 | s1 = t1 ^ bits.RotateLeft64(t1, -61) ^ bits.RotateLeft64(t1, -39) 159 | // x2 ← Σ2(x2) = x2 ⊕ (x2 ≫ 1) ⊕ (x2 ≫ 6) 160 | s2 = t2 ^ bits.RotateLeft64(t2, -1) ^ bits.RotateLeft64(t2, -6) 161 | // x3 ← Σ3(x3) = x3 ⊕ (x3 ≫ 10) ⊕ (x3 ≫ 17) 162 | s3 = t3 ^ bits.RotateLeft64(t3, -10) ^ bits.RotateLeft64(t3, -17) 163 | // x4 ← Σ4(x4) = x4 ⊕ (x4 ≫ 7) ⊕ (x4 ≫ 41) 164 | s4 = t4 ^ bits.RotateLeft64(t4, -7) ^ bits.RotateLeft64(t4, -41) 165 | } 166 | src = src[BlockSize128a:] 167 | dst = dst[BlockSize128a:] 168 | } 169 | s.x0 = s0 170 | s.x1 = s1 171 | s.x2 = s2 172 | s.x3 = s3 173 | s.x4 = s4 174 | } 175 | 176 | func roundGeneric(s *state, C uint64) { 177 | s0 := s.x0 178 | s1 := s.x1 179 | s2 := s.x2 180 | s3 := s.x3 181 | s4 := s.x4 182 | // Round constant 183 | s2 ^= C 184 | 185 | // Substitution 186 | s0 ^= s4 187 | s4 ^= s3 188 | s2 ^= s1 189 | 190 | // Keccak S-box 191 | t0 := s0 ^ (^s1 & s2) 192 | t1 := s1 ^ (^s2 & s3) 193 | t2 := s2 ^ (^s3 & s4) 194 | t3 := s3 ^ (^s4 & s0) 195 | t4 := s4 ^ (^s0 & s1) 196 | 197 | // Substitution 198 | t1 ^= t0 199 | t0 ^= t4 200 | t3 ^= t2 201 | t2 = ^t2 202 | 203 | // Linear diffusion 204 | // 205 | // x0 ← Σ0(x0) = x0 ⊕ (x0 ≫ 19) ⊕ (x0 ≫ 28) 206 | s0 = t0 ^ bits.RotateLeft64(t0, -19) ^ bits.RotateLeft64(t0, -28) 207 | // x1 ← Σ1(x1) = x1 ⊕ (x1 ≫ 61) ⊕ (x1 ≫ 39) 208 | s1 = t1 ^ bits.RotateLeft64(t1, -61) ^ bits.RotateLeft64(t1, -39) 209 | // x2 ← Σ2(x2) = x2 ⊕ (x2 ≫ 1) ⊕ (x2 ≫ 6) 210 | s2 = t2 ^ bits.RotateLeft64(t2, -1) ^ bits.RotateLeft64(t2, -6) 211 | // x3 ← Σ3(x3) = x3 ⊕ (x3 ≫ 10) ⊕ (x3 ≫ 17) 212 | s3 = t3 ^ bits.RotateLeft64(t3, -10) ^ bits.RotateLeft64(t3, -17) 213 | // x4 ← Σ4(x4) = x4 ⊕ (x4 ≫ 7) ⊕ (x4 ≫ 41) 214 | s4 = t4 ^ bits.RotateLeft64(t4, -7) ^ bits.RotateLeft64(t4, -41) 215 | s.x0 = s0 216 | s.x1 = s1 217 | s.x2 = s2 218 | s.x3 = s3 219 | s.x4 = s4 220 | } 221 | 222 | func p6Generic(s *state) { 223 | s0 := s.x0 224 | s1 := s.x1 225 | s2 := s.x2 226 | s3 := s.x3 227 | s4 := s.x4 228 | for C := uint64(150); C >= 74; C -= 15 { 229 | // Round constant 230 | s2 ^= C 231 | 232 | // Substitution 233 | s0 ^= s4 234 | s4 ^= s3 235 | s2 ^= s1 236 | 237 | // Keccak S-box 238 | t0 := s0 ^ (^s1 & s2) 239 | t1 := s1 ^ (^s2 & s3) 240 | t2 := s2 ^ (^s3 & s4) 241 | t3 := s3 ^ (^s4 & s0) 242 | t4 := s4 ^ (^s0 & s1) 243 | 244 | // Substitution 245 | t1 ^= t0 246 | t0 ^= t4 247 | t3 ^= t2 248 | t2 = ^t2 249 | 250 | // Linear diffusion 251 | // 252 | // x0 ← Σ0(x0) = x0 ⊕ (x0 ≫ 19) ⊕ (x0 ≫ 28) 253 | s0 = t0 ^ bits.RotateLeft64(t0, -19) ^ bits.RotateLeft64(t0, -28) 254 | // x1 ← Σ1(x1) = x1 ⊕ (x1 ≫ 61) ⊕ (x1 ≫ 39) 255 | s1 = t1 ^ bits.RotateLeft64(t1, -61) ^ bits.RotateLeft64(t1, -39) 256 | // x2 ← Σ2(x2) = x2 ⊕ (x2 ≫ 1) ⊕ (x2 ≫ 6) 257 | s2 = t2 ^ bits.RotateLeft64(t2, -1) ^ bits.RotateLeft64(t2, -6) 258 | // x3 ← Σ3(x3) = x3 ⊕ (x3 ≫ 10) ⊕ (x3 ≫ 17) 259 | s3 = t3 ^ bits.RotateLeft64(t3, -10) ^ bits.RotateLeft64(t3, -17) 260 | // x4 ← Σ4(x4) = x4 ⊕ (x4 ≫ 7) ⊕ (x4 ≫ 41) 261 | s4 = t4 ^ bits.RotateLeft64(t4, -7) ^ bits.RotateLeft64(t4, -41) 262 | } 263 | s.x0 = s0 264 | s.x1 = s1 265 | s.x2 = s2 266 | s.x3 = s3 267 | s.x4 = s4 268 | } 269 | 270 | func p8Generic(s *state) { 271 | s0 := s.x0 272 | s1 := s.x1 273 | s2 := s.x2 274 | s3 := s.x3 275 | s4 := s.x4 276 | for C := uint64(180); C >= 74; C -= 15 { 277 | // Round constant 278 | s2 ^= C 279 | 280 | // Substitution 281 | s0 ^= s4 282 | s4 ^= s3 283 | s2 ^= s1 284 | 285 | // Keccak S-box 286 | t0 := s0 ^ (^s1 & s2) 287 | t1 := s1 ^ (^s2 & s3) 288 | t2 := s2 ^ (^s3 & s4) 289 | t3 := s3 ^ (^s4 & s0) 290 | t4 := s4 ^ (^s0 & s1) 291 | 292 | // Substitution 293 | t1 ^= t0 294 | t0 ^= t4 295 | t3 ^= t2 296 | t2 = ^t2 297 | 298 | // Linear diffusion 299 | // 300 | // x0 ← Σ0(x0) = x0 ⊕ (x0 ≫ 19) ⊕ (x0 ≫ 28) 301 | s0 = t0 ^ bits.RotateLeft64(t0, -19) ^ bits.RotateLeft64(t0, -28) 302 | // x1 ← Σ1(x1) = x1 ⊕ (x1 ≫ 61) ⊕ (x1 ≫ 39) 303 | s1 = t1 ^ bits.RotateLeft64(t1, -61) ^ bits.RotateLeft64(t1, -39) 304 | // x2 ← Σ2(x2) = x2 ⊕ (x2 ≫ 1) ⊕ (x2 ≫ 6) 305 | s2 = t2 ^ bits.RotateLeft64(t2, -1) ^ bits.RotateLeft64(t2, -6) 306 | // x3 ← Σ3(x3) = x3 ⊕ (x3 ≫ 10) ⊕ (x3 ≫ 17) 307 | s3 = t3 ^ bits.RotateLeft64(t3, -10) ^ bits.RotateLeft64(t3, -17) 308 | // x4 ← Σ4(x4) = x4 ⊕ (x4 ≫ 7) ⊕ (x4 ≫ 41) 309 | s4 = t4 ^ bits.RotateLeft64(t4, -7) ^ bits.RotateLeft64(t4, -41) 310 | } 311 | s.x0 = s0 312 | s.x1 = s1 313 | s.x2 = s2 314 | s.x3 = s3 315 | s.x4 = s4 316 | } 317 | 318 | func p12Generic(s *state) { 319 | s0 := s.x0 320 | s1 := s.x1 321 | s2 := s.x2 322 | s3 := s.x3 323 | s4 := s.x4 324 | for C := uint64(240); C >= 74; C -= 15 { 325 | // Round constant 326 | s2 ^= C 327 | 328 | // Substitution 329 | s0 ^= s4 330 | s4 ^= s3 331 | s2 ^= s1 332 | 333 | // Keccak S-box 334 | t0 := s0 ^ (^s1 & s2) 335 | t1 := s1 ^ (^s2 & s3) 336 | t2 := s2 ^ (^s3 & s4) 337 | t3 := s3 ^ (^s4 & s0) 338 | t4 := s4 ^ (^s0 & s1) 339 | 340 | // Substitution 341 | t1 ^= t0 342 | t0 ^= t4 343 | t3 ^= t2 344 | t2 = ^t2 345 | 346 | // Linear diffusion 347 | // 348 | // x0 ← Σ0(x0) = x0 ⊕ (x0 ≫ 19) ⊕ (x0 ≫ 28) 349 | s0 = t0 ^ bits.RotateLeft64(t0, -19) ^ bits.RotateLeft64(t0, -28) 350 | // x1 ← Σ1(x1) = x1 ⊕ (x1 ≫ 61) ⊕ (x1 ≫ 39) 351 | s1 = t1 ^ bits.RotateLeft64(t1, -61) ^ bits.RotateLeft64(t1, -39) 352 | // x2 ← Σ2(x2) = x2 ⊕ (x2 ≫ 1) ⊕ (x2 ≫ 6) 353 | s2 = t2 ^ bits.RotateLeft64(t2, -1) ^ bits.RotateLeft64(t2, -6) 354 | // x3 ← Σ3(x3) = x3 ⊕ (x3 ≫ 10) ⊕ (x3 ≫ 17) 355 | s3 = t3 ^ bits.RotateLeft64(t3, -10) ^ bits.RotateLeft64(t3, -17) 356 | // x4 ← Σ4(x4) = x4 ⊕ (x4 ≫ 7) ⊕ (x4 ≫ 41) 357 | s4 = t4 ^ bits.RotateLeft64(t4, -7) ^ bits.RotateLeft64(t4, -41) 358 | } 359 | s.x0 = s0 360 | s.x1 = s1 361 | s.x2 = s2 362 | s.x3 = s3 363 | s.x4 = s4 364 | } 365 | -------------------------------------------------------------------------------- /grain/grain_amd64.s: -------------------------------------------------------------------------------- 1 | // Code generated by command: go run asm.go -out out/grain_amd64.s -stubs out/stub_amd64.go -pkg grain. DO NOT EDIT. 2 | 3 | // +build gc,!purego 4 | 5 | #include "textflag.h" 6 | 7 | // func next(s *state) uint32 8 | TEXT ·next(SB), NOSPLIT, $0-12 9 | // Load state 10 | MOVQ s+0(FP), AX 11 | 12 | // LFSR shifts 13 | // Load lfsr: (lo, hi) 14 | MOVQ 16(AX), CX 15 | MOVQ 24(AX), DX 16 | 17 | // Load lfsr words (u0, u1, u2, u3) 18 | // u0 = r.lo 19 | MOVQ CX, BX 20 | 21 | // u1 = r.lo>>32 | r.hi<<32 22 | MOVQ CX, SI 23 | SHRQ $0x20, SI 24 | MOVQ DX, DI 25 | SHLQ $0x20, DI 26 | ORQ DI, SI 27 | 28 | // u2 = r.hi 29 | MOVQ DX, DI 30 | 31 | // u3 = r.hi>>32 32 | MOVQ DX, R8 33 | SHRQ $0x20, R8 34 | 35 | // v := ln ^ ln3 36 | MOVQ BX, R9 37 | XORQ R8, R9 38 | 39 | // = ln1 ^ ln2 40 | MOVQ SI, R8 41 | XORQ DI, R8 42 | 43 | // v ^= ( >> 6) 44 | SHRQ $0x06, R8 45 | XORQ R8, R9 46 | 47 | // v ^= (ln0 >> 7) 48 | MOVQ BX, R8 49 | SHRQ $0x07, R8 50 | XORQ R8, R9 51 | 52 | // v ^= (ln2 >> 17) 53 | MOVQ DI, R8 54 | SHRQ $0x11, R8 55 | XORQ R8, R9 56 | 57 | // lo = r.lo>>32 | r.hi<<(64-32) 58 | SHRQ $0x20, CX 59 | MOVQ DX, R8 60 | SHLQ $0x20, R8 61 | ORQ R8, CX 62 | 63 | // r.hi>>32 | uint64(x)<<32 64 | SHRQ $0x20, DX 65 | MOVQ R9, R8 66 | SHLQ $0x20, R8 67 | ORQ R8, DX 68 | 69 | // Store lfsr: (lo, hi) 70 | MOVQ CX, 16(AX) 71 | MOVQ DX, 24(AX) 72 | 73 | // NFSR shifts 74 | // Load nfsr: (lo, hi) 75 | MOVQ 32(AX), CX 76 | MOVQ 40(AX), DX 77 | 78 | // Load nfsr words (u0, u1, u2, u3) 79 | // u0 = r.lo 80 | MOVQ CX, R10 81 | 82 | // u1 = r.lo>>32 | r.hi<<32 83 | MOVQ CX, R11 84 | SHRQ $0x20, R11 85 | MOVQ DX, R8 86 | SHLQ $0x20, R8 87 | ORQ R8, R11 88 | 89 | // u2 = r.hi 90 | MOVQ DX, R12 91 | 92 | // u3 = r.hi>>32 93 | MOVQ DX, R8 94 | SHRQ $0x20, R8 95 | 96 | // u := ln0 97 | MOVQ BX, R9 98 | 99 | // u ^= nn0 100 | XORQ R10, R9 101 | 102 | // u ^= (nn0 >> 26) 103 | MOVQ R10, R13 104 | SHRQ $0x1a, R13 105 | XORQ R13, R9 106 | XORQ R8, R9 107 | 108 | // u ^= (nn1 >> 24) 109 | MOVQ R11, R8 110 | SHRQ $0x18, R8 111 | XORQ R8, R9 112 | 113 | // = (nn0 & nn2) ^ nn2 114 | MOVQ R11, R8 115 | ANDQ R10, R8 116 | XORQ R12, R8 117 | 118 | // u ^= ( >> 27) 119 | SHRQ $0x1b, R8 120 | XORQ R8, R9 121 | 122 | // = nn0 & nn2 123 | MOVQ R12, R8 124 | ANDQ R10, R8 125 | 126 | // u ^= ( >> 3) 127 | SHRQ $0x03, R8 128 | XORQ R8, R9 129 | 130 | // u ^= (nn0 >> 11) & (nn0 >> 13) 131 | MOVQ R10, R8 132 | SHRQ $0x0b, R8 133 | MOVQ R10, R13 134 | SHRQ $0x0d, R13 135 | ANDQ R13, R8 136 | XORQ R8, R9 137 | 138 | // u ^= (nn0 >> 17) & (nn0 >> 18) 139 | MOVQ R10, R8 140 | SHRQ $0x11, R8 141 | MOVQ R10, R13 142 | SHRQ $0x12, R13 143 | ANDQ R13, R8 144 | XORQ R8, R9 145 | 146 | // u ^= (nn1 >> 8) & (nn1 >> 16) 147 | MOVQ R11, R8 148 | SHRQ $0x08, R8 149 | MOVQ R11, R13 150 | SHRQ $0x10, R13 151 | ANDQ R13, R8 152 | XORQ R8, R9 153 | 154 | // u ^= (nn1 >> 29) & (nn2 >> 1) 155 | MOVQ R11, R8 156 | SHRQ $0x1d, R8 157 | MOVQ R12, R13 158 | SHRQ $0x01, R13 159 | ANDQ R13, R8 160 | XORQ R8, R9 161 | 162 | // u ^= (nn2 >> 4) & (nn2 >> 20) 163 | MOVQ R12, R8 164 | SHRQ $0x04, R8 165 | MOVQ R12, R13 166 | SHRQ $0x14, R13 167 | ANDQ R13, R8 168 | XORQ R8, R9 169 | 170 | // u ^= (nn2 >> 24) & (nn2 >> 28) & (nn2 >> 29) & (nn2 >> 31) 171 | MOVQ R12, R8 172 | SHRQ $0x18, R8 173 | MOVQ R12, R13 174 | SHRQ $0x1c, R13 175 | ANDQ R13, R8 176 | MOVQ R12, R13 177 | SHRQ $0x1d, R13 178 | ANDQ R13, R8 179 | MOVQ R12, R13 180 | SHRQ $0x1f, R13 181 | ANDQ R13, R8 182 | XORQ R8, R9 183 | 184 | // u ^= (nn0 >> 22) & (nn0 >> 24) & (nn0 >> 25) 185 | MOVQ R10, R8 186 | SHRQ $0x16, R8 187 | MOVQ R10, R13 188 | SHRQ $0x18, R13 189 | ANDQ R13, R8 190 | MOVQ R10, R13 191 | SHRQ $0x19, R13 192 | ANDQ R13, R8 193 | XORQ R8, R9 194 | 195 | // u ^= (nn2 >> 6) & (nn2 >> 14) & (nn2 >> 18) 196 | MOVQ R12, R8 197 | SHRQ $0x06, R8 198 | MOVQ R12, R13 199 | SHRQ $0x0e, R13 200 | ANDQ R13, R8 201 | MOVQ R12, R13 202 | SHRQ $0x12, R13 203 | ANDQ R13, R8 204 | XORQ R8, R9 205 | 206 | // lo = r.lo>>32 | r.hi<<(64-32) 207 | SHRQ $0x20, CX 208 | MOVQ DX, R8 209 | SHLQ $0x20, R8 210 | ORQ R8, CX 211 | 212 | // r.hi>>32 | uint64(x)<<32 213 | SHRQ $0x20, DX 214 | MOVQ R9, R8 215 | SHLQ $0x20, R8 216 | ORQ R8, DX 217 | 218 | // Store nfsr: (lo, hi) 219 | MOVQ CX, 32(AX) 220 | MOVQ DX, 40(AX) 221 | MOVQ R10, R9 222 | SHRQ $0x02, R9 223 | 224 | // x ^= (nn0 >> 15) 225 | MOVQ R10, AX 226 | SHRQ $0x0f, AX 227 | XORQ AX, R9 228 | 229 | // x ^= (nn1 >> 4) 230 | MOVQ R11, AX 231 | SHRQ $0x04, AX 232 | XORQ AX, R9 233 | 234 | // x ^= (nn1 >> 13) 235 | MOVQ R11, AX 236 | SHRQ $0x0d, AX 237 | XORQ AX, R9 238 | XORQ R12, R9 239 | 240 | // x ^= (nn2 >> 9) 241 | MOVQ R12, AX 242 | SHRQ $0x09, AX 243 | XORQ AX, R9 244 | 245 | // x ^= (nn2 >> 25) 246 | MOVQ R12, AX 247 | SHRQ $0x19, AX 248 | XORQ AX, R9 249 | 250 | // x ^= (ln2 >> 29) 251 | MOVQ DI, AX 252 | SHRQ $0x1d, AX 253 | XORQ AX, R9 254 | 255 | // x ^= (nn0 >> 12) & (ln0 >> 8) 256 | MOVQ R10, AX 257 | SHRQ $0x0c, AX 258 | MOVQ BX, CX 259 | SHRQ $0x08, CX 260 | ANDQ CX, AX 261 | XORQ AX, R9 262 | 263 | // x ^= (ln0 >> 13) & (ln0 >> 20) 264 | MOVQ BX, AX 265 | SHRQ $0x0d, AX 266 | MOVQ BX, CX 267 | SHRQ $0x14, CX 268 | ANDQ CX, AX 269 | XORQ AX, R9 270 | 271 | // x ^= (nn2 >> 31) & (ln1 >> 10) 272 | MOVQ R12, AX 273 | SHRQ $0x1f, AX 274 | MOVQ SI, CX 275 | SHRQ $0x0a, CX 276 | ANDQ CX, AX 277 | XORQ AX, R9 278 | 279 | // x ^= (ln1 >> 28) & (ln2 >> 15) 280 | MOVQ SI, AX 281 | SHRQ $0x1c, AX 282 | MOVQ DI, CX 283 | SHRQ $0x0f, CX 284 | ANDQ CX, AX 285 | XORQ AX, R9 286 | 287 | // x ^= (nn0 >> 12) & (nn2 >> 31) & (ln2 >> 30) 288 | MOVQ R10, AX 289 | SHRQ $0x0c, AX 290 | MOVQ R12, CX 291 | SHRQ $0x1f, CX 292 | ANDQ CX, AX 293 | MOVQ DI, CX 294 | SHRQ $0x1e, CX 295 | ANDQ CX, AX 296 | XORQ AX, R9 297 | 298 | // Store result 299 | MOVL R9, ret+8(FP) 300 | RET 301 | 302 | // func accumulate(reg uint64, acc uint64, ms uint16, pt uint16) (reg1 uint64, acc1 uint64) 303 | TEXT ·accumulate(SB), NOSPLIT, $0-40 304 | MOVQ reg+0(FP), AX 305 | MOVQ acc+8(FP), CX 306 | MOVWLZX pt+18(FP), DX 307 | MOVWQZX ms+16(FP), BX 308 | 309 | // var acctmp uint16 310 | XORQ SI, SI 311 | 312 | // regtmp := uint32(ms) << 16 313 | MOVWLZX BX, DI 314 | SHLL $0x10, DI 315 | 316 | // mask := -uint64(pt & 1) 317 | MOVL DX, R8 318 | ANDL $0x01, R8 319 | NEGQ R8 320 | 321 | // acc ^= reg & mask 322 | MOVQ AX, R9 323 | ANDQ R8, R9 324 | XORQ R9, CX 325 | 326 | // acctmp ^= uint16(regtmp) & uint16(mask) 327 | ANDW DI, R8 328 | XORW R8, SI 329 | 330 | // reg >>= 1 331 | SHRQ $0x01, AX 332 | 333 | // pt >>= 1 334 | SHRL $0x01, DX 335 | 336 | // regtmp >>= 1 337 | SHRL $0x01, DI 338 | 339 | // mask := -uint64(pt & 1) 340 | MOVL DX, R8 341 | ANDL $0x01, R8 342 | NEGQ R8 343 | 344 | // acc ^= reg & mask 345 | MOVQ AX, R9 346 | ANDQ R8, R9 347 | XORQ R9, CX 348 | 349 | // acctmp ^= uint16(regtmp) & uint16(mask) 350 | ANDW DI, R8 351 | XORW R8, SI 352 | 353 | // reg >>= 1 354 | SHRQ $0x01, AX 355 | 356 | // pt >>= 1 357 | SHRL $0x01, DX 358 | 359 | // regtmp >>= 1 360 | SHRL $0x01, DI 361 | 362 | // mask := -uint64(pt & 1) 363 | MOVL DX, R8 364 | ANDL $0x01, R8 365 | NEGQ R8 366 | 367 | // acc ^= reg & mask 368 | MOVQ AX, R9 369 | ANDQ R8, R9 370 | XORQ R9, CX 371 | 372 | // acctmp ^= uint16(regtmp) & uint16(mask) 373 | ANDW DI, R8 374 | XORW R8, SI 375 | 376 | // reg >>= 1 377 | SHRQ $0x01, AX 378 | 379 | // pt >>= 1 380 | SHRL $0x01, DX 381 | 382 | // regtmp >>= 1 383 | SHRL $0x01, DI 384 | 385 | // mask := -uint64(pt & 1) 386 | MOVL DX, R8 387 | ANDL $0x01, R8 388 | NEGQ R8 389 | 390 | // acc ^= reg & mask 391 | MOVQ AX, R9 392 | ANDQ R8, R9 393 | XORQ R9, CX 394 | 395 | // acctmp ^= uint16(regtmp) & uint16(mask) 396 | ANDW DI, R8 397 | XORW R8, SI 398 | 399 | // reg >>= 1 400 | SHRQ $0x01, AX 401 | 402 | // pt >>= 1 403 | SHRL $0x01, DX 404 | 405 | // regtmp >>= 1 406 | SHRL $0x01, DI 407 | 408 | // mask := -uint64(pt & 1) 409 | MOVL DX, R8 410 | ANDL $0x01, R8 411 | NEGQ R8 412 | 413 | // acc ^= reg & mask 414 | MOVQ AX, R9 415 | ANDQ R8, R9 416 | XORQ R9, CX 417 | 418 | // acctmp ^= uint16(regtmp) & uint16(mask) 419 | ANDW DI, R8 420 | XORW R8, SI 421 | 422 | // reg >>= 1 423 | SHRQ $0x01, AX 424 | 425 | // pt >>= 1 426 | SHRL $0x01, DX 427 | 428 | // regtmp >>= 1 429 | SHRL $0x01, DI 430 | 431 | // mask := -uint64(pt & 1) 432 | MOVL DX, R8 433 | ANDL $0x01, R8 434 | NEGQ R8 435 | 436 | // acc ^= reg & mask 437 | MOVQ AX, R9 438 | ANDQ R8, R9 439 | XORQ R9, CX 440 | 441 | // acctmp ^= uint16(regtmp) & uint16(mask) 442 | ANDW DI, R8 443 | XORW R8, SI 444 | 445 | // reg >>= 1 446 | SHRQ $0x01, AX 447 | 448 | // pt >>= 1 449 | SHRL $0x01, DX 450 | 451 | // regtmp >>= 1 452 | SHRL $0x01, DI 453 | 454 | // mask := -uint64(pt & 1) 455 | MOVL DX, R8 456 | ANDL $0x01, R8 457 | NEGQ R8 458 | 459 | // acc ^= reg & mask 460 | MOVQ AX, R9 461 | ANDQ R8, R9 462 | XORQ R9, CX 463 | 464 | // acctmp ^= uint16(regtmp) & uint16(mask) 465 | ANDW DI, R8 466 | XORW R8, SI 467 | 468 | // reg >>= 1 469 | SHRQ $0x01, AX 470 | 471 | // pt >>= 1 472 | SHRL $0x01, DX 473 | 474 | // regtmp >>= 1 475 | SHRL $0x01, DI 476 | 477 | // mask := -uint64(pt & 1) 478 | MOVL DX, R8 479 | ANDL $0x01, R8 480 | NEGQ R8 481 | 482 | // acc ^= reg & mask 483 | MOVQ AX, R9 484 | ANDQ R8, R9 485 | XORQ R9, CX 486 | 487 | // acctmp ^= uint16(regtmp) & uint16(mask) 488 | ANDW DI, R8 489 | XORW R8, SI 490 | 491 | // reg >>= 1 492 | SHRQ $0x01, AX 493 | 494 | // pt >>= 1 495 | SHRL $0x01, DX 496 | 497 | // regtmp >>= 1 498 | SHRL $0x01, DI 499 | 500 | // mask := -uint64(pt & 1) 501 | MOVL DX, R8 502 | ANDL $0x01, R8 503 | NEGQ R8 504 | 505 | // acc ^= reg & mask 506 | MOVQ AX, R9 507 | ANDQ R8, R9 508 | XORQ R9, CX 509 | 510 | // acctmp ^= uint16(regtmp) & uint16(mask) 511 | ANDW DI, R8 512 | XORW R8, SI 513 | 514 | // reg >>= 1 515 | SHRQ $0x01, AX 516 | 517 | // pt >>= 1 518 | SHRL $0x01, DX 519 | 520 | // regtmp >>= 1 521 | SHRL $0x01, DI 522 | 523 | // mask := -uint64(pt & 1) 524 | MOVL DX, R8 525 | ANDL $0x01, R8 526 | NEGQ R8 527 | 528 | // acc ^= reg & mask 529 | MOVQ AX, R9 530 | ANDQ R8, R9 531 | XORQ R9, CX 532 | 533 | // acctmp ^= uint16(regtmp) & uint16(mask) 534 | ANDW DI, R8 535 | XORW R8, SI 536 | 537 | // reg >>= 1 538 | SHRQ $0x01, AX 539 | 540 | // pt >>= 1 541 | SHRL $0x01, DX 542 | 543 | // regtmp >>= 1 544 | SHRL $0x01, DI 545 | 546 | // mask := -uint64(pt & 1) 547 | MOVL DX, R8 548 | ANDL $0x01, R8 549 | NEGQ R8 550 | 551 | // acc ^= reg & mask 552 | MOVQ AX, R9 553 | ANDQ R8, R9 554 | XORQ R9, CX 555 | 556 | // acctmp ^= uint16(regtmp) & uint16(mask) 557 | ANDW DI, R8 558 | XORW R8, SI 559 | 560 | // reg >>= 1 561 | SHRQ $0x01, AX 562 | 563 | // pt >>= 1 564 | SHRL $0x01, DX 565 | 566 | // regtmp >>= 1 567 | SHRL $0x01, DI 568 | 569 | // mask := -uint64(pt & 1) 570 | MOVL DX, R8 571 | ANDL $0x01, R8 572 | NEGQ R8 573 | 574 | // acc ^= reg & mask 575 | MOVQ AX, R9 576 | ANDQ R8, R9 577 | XORQ R9, CX 578 | 579 | // acctmp ^= uint16(regtmp) & uint16(mask) 580 | ANDW DI, R8 581 | XORW R8, SI 582 | 583 | // reg >>= 1 584 | SHRQ $0x01, AX 585 | 586 | // pt >>= 1 587 | SHRL $0x01, DX 588 | 589 | // regtmp >>= 1 590 | SHRL $0x01, DI 591 | 592 | // mask := -uint64(pt & 1) 593 | MOVL DX, R8 594 | ANDL $0x01, R8 595 | NEGQ R8 596 | 597 | // acc ^= reg & mask 598 | MOVQ AX, R9 599 | ANDQ R8, R9 600 | XORQ R9, CX 601 | 602 | // acctmp ^= uint16(regtmp) & uint16(mask) 603 | ANDW DI, R8 604 | XORW R8, SI 605 | 606 | // reg >>= 1 607 | SHRQ $0x01, AX 608 | 609 | // pt >>= 1 610 | SHRL $0x01, DX 611 | 612 | // regtmp >>= 1 613 | SHRL $0x01, DI 614 | 615 | // mask := -uint64(pt & 1) 616 | MOVL DX, R8 617 | ANDL $0x01, R8 618 | NEGQ R8 619 | 620 | // acc ^= reg & mask 621 | MOVQ AX, R9 622 | ANDQ R8, R9 623 | XORQ R9, CX 624 | 625 | // acctmp ^= uint16(regtmp) & uint16(mask) 626 | ANDW DI, R8 627 | XORW R8, SI 628 | 629 | // reg >>= 1 630 | SHRQ $0x01, AX 631 | 632 | // pt >>= 1 633 | SHRL $0x01, DX 634 | 635 | // regtmp >>= 1 636 | SHRL $0x01, DI 637 | 638 | // mask := -uint64(pt & 1) 639 | MOVL DX, R8 640 | ANDL $0x01, R8 641 | NEGQ R8 642 | 643 | // acc ^= reg & mask 644 | MOVQ AX, R9 645 | ANDQ R8, R9 646 | XORQ R9, CX 647 | 648 | // acctmp ^= uint16(regtmp) & uint16(mask) 649 | ANDW DI, R8 650 | XORW R8, SI 651 | 652 | // reg >>= 1 653 | SHRQ $0x01, AX 654 | 655 | // pt >>= 1 656 | SHRL $0x01, DX 657 | 658 | // regtmp >>= 1 659 | SHRL $0x01, DI 660 | 661 | // mask := -uint64(pt & 1) 662 | MOVL DX, R8 663 | ANDL $0x01, R8 664 | NEGQ R8 665 | 666 | // acc ^= reg & mask 667 | MOVQ AX, R9 668 | ANDQ R8, R9 669 | XORQ R9, CX 670 | 671 | // acctmp ^= uint16(regtmp) & uint16(mask) 672 | ANDW DI, R8 673 | XORW R8, SI 674 | 675 | // reg >>= 1 676 | SHRQ $0x01, AX 677 | 678 | // pt >>= 1 679 | SHRL $0x01, DX 680 | 681 | // reg |= uint64(ms) << 48 682 | // acc ^= uint64(acctmp) << 48 683 | SHLQ $0x30, BX 684 | SHLQ $0x30, SI 685 | ORQ BX, AX 686 | XORQ SI, CX 687 | 688 | // Store results 689 | MOVQ AX, reg1+24(FP) 690 | MOVQ CX, acc1+32(FP) 691 | RET 692 | -------------------------------------------------------------------------------- /grain/grain.go: -------------------------------------------------------------------------------- 1 | // Package grain implements the Grain128-AEAD cipher. 2 | // 3 | // Performance 4 | // 5 | // For 1 KiB plaintext, this implementation runs at about 40-50 6 | // cycles per byte (tested on a 2020 MacBook Air M1 @ 3.2Ghz and 7 | // a 2019 Macbook Pro i7 @ 2.6Ghz). This is roughly equivalent 8 | // to the optimized C implementation [m1,x86]. 9 | // 10 | // This implementation runs at about 11 | // 12 | // References: 13 | // 14 | // [grain]: https://grain-128aead.github.io/ 15 | // [m1]: https://gist.github.com/ericlagergren/645eb97a05efd37152d6f1cfa9cf9d4a 16 | // [x86]: https://gist.github.com/elagergren-spideroak/4bd31a59925de3b19227d4ae80b55cf0 17 | // 18 | package grain 19 | 20 | import ( 21 | "crypto/cipher" 22 | "encoding/binary" 23 | "errors" 24 | "fmt" 25 | "math/bits" 26 | "runtime" 27 | "strconv" 28 | "strings" 29 | 30 | "github.com/ericlagergren/subtle" 31 | ) 32 | 33 | var errOpen = errors.New("grain: message authentication failed") 34 | 35 | const ( 36 | // BlockSize is the size in bytes of an Grain128-AEAD block. 37 | BlockSize = 16 38 | // KeySize is the size in bytes of an Grain128-AEAD key. 39 | KeySize = 16 40 | // NonceSize is the size in bytes of an Grain128-AEAD nonce. 41 | NonceSize = 12 42 | // TagSize is the size in bytes of an Grain128-AEAD 43 | // authenticator. 44 | TagSize = 8 45 | ) 46 | 47 | // NewUnauthenticated creates a Grain128a stream cipher. 48 | // 49 | // Grain128a must not be used to encrypt more than 2^80 bits per 50 | // key, nonce pair. 51 | func NewUnauthenticated(key, nonce []byte) (cipher.Stream, error) { 52 | if len(key) != KeySize { 53 | return nil, errors.New("grain: bad key length") 54 | } 55 | var s stream 56 | s.s.setKey(key) 57 | s.s.init(nonce) 58 | return &s, nil 59 | } 60 | 61 | // stream implements cipher.Stream. 62 | type stream struct { 63 | s state 64 | // ks is a remaining key stream byte, if any. 65 | // 66 | // There is a remaining key stream byte, its high bits will 67 | // be set. 68 | ks uint16 69 | } 70 | 71 | var _ cipher.Stream = (*stream)(nil) 72 | 73 | func (s *stream) XORKeyStream(dst, src []byte) { 74 | if len(src) == 0 { 75 | return 76 | } 77 | if len(dst) < len(src) { 78 | panic("grain: output smaller than input") 79 | } 80 | dst = dst[:len(src)] 81 | if subtle.InexactOverlap(dst, src) { 82 | panic("grain: invalid buffer overlap") 83 | } 84 | 85 | // Remaining key stream. 86 | const mask = 0xff00 87 | if s.ks&mask != 0 { 88 | dst[0] = src[0] ^ byte(s.ks) 89 | src = src[1:] 90 | dst = dst[1:] 91 | } 92 | 93 | for len(src) >= 2 { 94 | v := binary.LittleEndian.Uint16(src) 95 | binary.LittleEndian.PutUint16(dst, v^getkb(next(&s.s))) 96 | src = src[2:] 97 | dst = dst[2:] 98 | } 99 | 100 | if len(src) > 0 { 101 | w := getkb(next(&s.s)) 102 | s.ks = mask | w>>8 103 | dst[0] = src[0] ^ byte(w) 104 | } else { 105 | s.ks = 0 106 | } 107 | } 108 | 109 | // state is the pure Go "generic" implementation of 110 | // Grain-128AEAD. 111 | // 112 | // Grain-128AEAD has two primary parts: 113 | // 114 | // 1. pre-output generator 115 | // 2. authenticator generator 116 | // 117 | // The pre-output generator has three parts: 118 | // 119 | // 1. an LFSR 120 | // 2. a non-linear FSR (NFSR) 121 | // 3. a pre-output function 122 | // 123 | // The authenticator generator has two parts: 124 | // 125 | // 1. a shift register 126 | // 2. an accumulator 127 | // 128 | // The pre-output generator is defined as 129 | // 130 | // y_t = h(x) + s_93^t + \sum_{j \in A} b_j^t 131 | // 132 | // where 133 | // 134 | // A = {2, 15, 36, 45, 64, 73, 89} 135 | // 136 | type state struct { 137 | // key is the 128-bit key. 138 | key [4]uint32 139 | // lfsr is a 128-bit linear feedback shift register. 140 | // 141 | // The LFSR is defined as the following polynomial over GF(2) 142 | // 143 | // f(x) = 1 + x^32 + x^47 + x^58 + x^90 + x^121 + x^128 144 | // 145 | // and updated with 146 | // 147 | // s_127^(t+1) = s_0^t + s_7^t + s_38^t 148 | // + s_70^t + s_81^t + s_96^t 149 | // = L(S_t) 150 | lfsr lfsr 151 | // nfsr is a 128-bit non-linear feedback shift register. 152 | // 153 | // nfsr is defined as the following polynomial over GF(2) 154 | // 155 | // g(x) = 1 + x^32 + x^37 + x^72 + x^102 + x^128 156 | // + x^44*x^60 + x^61*x^125 + x^63*x^67 157 | // + x^69*x^101 + x^80*x^88 + x^110*x^111 158 | // + x^115*x^117 + x^46*x^50*x^58 159 | // + x^103*x^104*x^106 + x^33*x^35*x^36*x^40 160 | // 161 | // and updated with 162 | // 163 | // b_126^(t+1) = s_0^t + b_0^t + b_26^t + b_56^t 164 | // + b_91^t + b_96^t + b_3^t*b_67^t 165 | // + b_11^t*b_13^t + b_17^t*b_18^t 166 | // + b_27^t*b_59^t + b_40^t*b_48^t 167 | // + b_61^t*b_65^t + b_68^t*b_84^t 168 | // + b_22^t*b_24^t*b_25^t 169 | // + b_70^t*b_78^t*b_82^t 170 | // + b_88^t*b_92^t*b_93^t*b_95^t 171 | // = s_0^t + F(B_t) 172 | nfsr nfsr 173 | // acc is the accumulator half of the authentication 174 | // generator. 175 | // 176 | // Specifically, acc is the authentication tag. 177 | acc uint64 178 | // reg is the shift register half of the authentication 179 | // generaetor, containing the most recent 64 odd bits from 180 | // the pre-output. 181 | reg uint64 182 | } 183 | 184 | var _ cipher.AEAD = (*state)(nil) 185 | 186 | // New creates a 128-bit Grain128-AEAD AEAD. 187 | // 188 | // Grain128-AEAD must not be used to encrypt more than 2^80 bits 189 | // per key, nonce pair, including additional authenticated data. 190 | func New(key []byte) (cipher.AEAD, error) { 191 | if len(key) != KeySize { 192 | return nil, errors.New("grain: bad key length") 193 | } 194 | var s state 195 | s.setKey(key) 196 | return &s, nil 197 | } 198 | 199 | func (s *state) NonceSize() int { 200 | return NonceSize 201 | } 202 | 203 | func (s *state) Overhead() int { 204 | return TagSize 205 | } 206 | 207 | func (s *state) Seal(dst, nonce, plaintext, additionalData []byte) []byte { 208 | if len(nonce) != NonceSize { 209 | panic("grain: incorrect nonce length: " + strconv.Itoa(len(nonce))) 210 | } 211 | s.init(nonce) 212 | 213 | ret, out := subtle.SliceForAppend(dst, len(plaintext)+TagSize) 214 | if subtle.InexactOverlap(out, plaintext) { 215 | panic("grain: invalid buffer overlap") 216 | } 217 | 218 | s.encrypt(out[:len(out)-TagSize], plaintext, additionalData) 219 | 220 | s.tag(out[len(out)-TagSize:]) 221 | 222 | return ret 223 | } 224 | 225 | func (s *state) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { 226 | if len(nonce) != NonceSize { 227 | panic("grain: incorrect nonce length: " + strconv.Itoa(len(nonce))) 228 | } 229 | if len(ciphertext) < TagSize { 230 | return nil, errOpen 231 | } 232 | s.init(nonce) 233 | 234 | tag := ciphertext[len(ciphertext)-TagSize:] 235 | ciphertext = ciphertext[:len(ciphertext)-TagSize] 236 | 237 | ret, out := subtle.SliceForAppend(dst, len(ciphertext)) 238 | if subtle.InexactOverlap(out, ciphertext) { 239 | panic("grain: invalid buffer overlap") 240 | } 241 | 242 | s.decrypt(out, ciphertext, additionalData) 243 | 244 | expectedTag := make([]byte, TagSize) 245 | s.tag(expectedTag) 246 | 247 | if subtle.ConstantTimeCompare(expectedTag, tag) != 1 { 248 | for i := range out { 249 | out[i] = 0 250 | } 251 | runtime.KeepAlive(out) 252 | return nil, errOpen 253 | } 254 | return ret, nil 255 | } 256 | 257 | func (s *state) encrypt(dst, src, ad []byte) { 258 | // der contains the DER-encoded length of ad. Always ensure 259 | // that DER has an even number of bytes to simplify the 260 | // following loops. 261 | var der []byte 262 | if len(ad) <= shortInt { 263 | // Use DER's "short" encoding. 264 | if len(ad) > 0 { 265 | der = []byte{byte(len(ad)), ad[0]} 266 | ad = ad[1:] 267 | } else { 268 | ad = []byte{byte(len(ad))} 269 | } 270 | } else { 271 | d := encode(len(ad)) 272 | n := d.len() 273 | if n%2 != 0 { 274 | d[n] = ad[0] 275 | ad = ad[1:] 276 | n++ 277 | } 278 | der = d[:n] 279 | } 280 | 281 | for len(der) > 0 { 282 | v := binary.LittleEndian.Uint16(der) 283 | s.reg, s.acc = accumulate(s.reg, s.acc, getmb(next(s)), v) 284 | der = der[2:] 285 | } 286 | 287 | for len(ad) >= 2 { 288 | v := binary.LittleEndian.Uint16(ad) 289 | s.reg, s.acc = accumulate(s.reg, s.acc, getmb(next(s)), v) 290 | ad = ad[2:] 291 | } 292 | 293 | if len(ad) > 0 { 294 | word := next(s) 295 | s.accumulate8(uint8(getmb(word)), ad[0]) 296 | if len(src) > 0 { 297 | dst[0] = uint8(getkb(word)>>8) ^ src[0] 298 | s.accumulate8(uint8(getmb(word)>>8), src[0]) 299 | src = src[1:] 300 | dst = dst[1:] 301 | } 302 | } 303 | 304 | for len(src) >= 2 { 305 | next := next(s) 306 | v := binary.LittleEndian.Uint16(src) 307 | binary.LittleEndian.PutUint16(dst, getkb(next)^v) 308 | s.reg, s.acc = accumulate(s.reg, s.acc, getmb(next), v) 309 | src = src[2:] 310 | dst = dst[2:] 311 | } 312 | 313 | if len(src) > 0 { 314 | word := next(s) 315 | dst[0] = byte(getkb(word)) ^ src[0] 316 | s.reg, s.acc = accumulate(s.reg, s.acc, getmb(word), 317 | 0x100|uint16(src[0])) 318 | } else { 319 | s.reg, s.acc = accumulate(s.reg, s.acc, getmb(next(s)), 0x01) 320 | } 321 | } 322 | 323 | func (s *state) decrypt(dst, src, ad []byte) { 324 | // der contains the DER-encoded length of ad. Always ensure 325 | // that DER has an even number of bytes to simplify the 326 | // following loops. 327 | var der []byte 328 | if len(ad) <= shortInt { 329 | if len(ad) > 0 { 330 | der = []byte{byte(len(ad)), ad[0]} 331 | ad = ad[1:] 332 | } else { 333 | ad = []byte{byte(len(ad))} 334 | } 335 | } else { 336 | d := encode(len(ad)) 337 | n := d.len() 338 | if n%2 != 0 { 339 | d[n] = ad[0] 340 | ad = ad[1:] 341 | n++ 342 | } 343 | der = d[:n] 344 | } 345 | 346 | for len(der) > 0 { 347 | v := binary.LittleEndian.Uint16(der) 348 | s.reg, s.acc = accumulate(s.reg, s.acc, getmb(next(s)), v) 349 | der = der[2:] 350 | } 351 | 352 | for len(ad) >= 2 { 353 | v := binary.LittleEndian.Uint16(ad) 354 | s.reg, s.acc = accumulate(s.reg, s.acc, getmb(next(s)), v) 355 | ad = ad[2:] 356 | } 357 | 358 | if len(ad) > 0 { 359 | word := next(s) 360 | s.accumulate8(uint8(getmb(word)), ad[0]) 361 | if len(src) > 0 { 362 | dst[0] = uint8(getkb(word)>>8) ^ src[0] 363 | s.accumulate8(uint8(getmb(word)>>8), dst[0]) 364 | src = src[1:] 365 | dst = dst[1:] 366 | } 367 | } 368 | 369 | for len(src) >= 2 { 370 | next := next(s) 371 | v := getkb(next) ^ binary.LittleEndian.Uint16(src) 372 | binary.LittleEndian.PutUint16(dst, v) 373 | s.reg, s.acc = accumulate(s.reg, s.acc, getmb(next), v) 374 | src = src[2:] 375 | dst = dst[2:] 376 | } 377 | 378 | if len(src) > 0 { 379 | word := next(s) 380 | dst[0] = byte(getkb(word)) ^ src[0] 381 | s.reg, s.acc = accumulate(s.reg, s.acc, getmb(word), 382 | 0x100|uint16(dst[0])) 383 | } else { 384 | s.reg, s.acc = accumulate(s.reg, s.acc, getmb(next(s)), 0x01) 385 | } 386 | } 387 | 388 | func (s *state) tag(dst []byte) { 389 | binary.LittleEndian.PutUint64(dst, s.acc) 390 | } 391 | 392 | func (s *state) setKey(key []byte) { 393 | _ = key[15] // bounds check hint to compiler 394 | s.key[0] = binary.LittleEndian.Uint32(key[0:4]) 395 | s.key[1] = binary.LittleEndian.Uint32(key[4:8]) 396 | s.key[2] = binary.LittleEndian.Uint32(key[8:12]) 397 | s.key[3] = binary.LittleEndian.Uint32(key[12:16]) 398 | } 399 | 400 | func (s *state) init(nonce []byte) { 401 | for _, k := range s.key { 402 | s.nfsr = s.nfsr.shift(k) 403 | } 404 | 405 | for i := 0; i < 12; i += 4 { 406 | s.lfsr = s.lfsr.shift(binary.LittleEndian.Uint32(nonce[i : i+4])) 407 | } 408 | s.lfsr = s.lfsr.shift(1<<31 - 1) 409 | 410 | for i := 0; i < 8; i++ { 411 | ks := next(s) 412 | s.lfsr = s.lfsr.xor(ks) 413 | s.nfsr = s.nfsr.xor(ks) 414 | } 415 | 416 | s.acc = 0 417 | for i := 0; i < 2; i++ { 418 | ks := next(s) 419 | s.acc |= uint64(ks) << (32 * i) 420 | s.lfsr = s.lfsr.xor(s.key[i]) 421 | } 422 | 423 | s.reg = 0 424 | for i := 0; i < 2; i++ { 425 | ks := next(s) 426 | s.reg |= uint64(ks) << (32 * i) 427 | s.lfsr = s.lfsr.xor(s.key[i+2]) 428 | } 429 | } 430 | 431 | func nextGeneric(s *state) uint32 { 432 | ln0, ln1, ln2, ln3 := s.lfsr.words() 433 | 434 | v := ln0 ^ ln3 435 | v ^= (ln1 ^ ln2) >> 6 436 | v ^= ln0 >> 7 437 | v ^= ln2 >> 17 438 | s.lfsr = s.lfsr.shift(uint32(v)) 439 | 440 | nn0, nn1, nn2, nn3 := s.nfsr.words() 441 | 442 | u := ln0 // s_0 443 | u ^= nn0 // b_0 444 | u ^= nn0 >> 26 // b_26 445 | u ^= nn3 // b_93 446 | u ^= nn1 >> 24 // b_56 447 | u ^= ((nn0 & nn1) ^ nn2) >> 27 // b_91 + b_27*b_59 448 | u ^= (nn0 & nn2) >> 3 // b_3*b_67 449 | u ^= (nn0 >> 11) & (nn0 >> 13) // b_11*b_13 450 | u ^= (nn0 >> 17) & (nn0 >> 18) // b_17*b_18 451 | u ^= (nn1 >> 8) & (nn1 >> 16) // b_40*b_48 452 | u ^= (nn1 >> 29) & (nn2 >> 1) // b_61*b_65 453 | u ^= (nn2 >> 4) & (nn2 >> 20) // b_68*b_84 454 | u ^= (nn2 >> 24) & (nn2 >> 28) & (nn2 >> 29) & (nn2 >> 31) // b_88*b_92*b_93*b_95 455 | u ^= (nn0 >> 22) & (nn0 >> 24) & (nn0 >> 25) // b_22*b_24*b_25 456 | u ^= (nn2 >> 6) & (nn2 >> 14) & (nn2 >> 18) // b_70*b_78*b_82 457 | s.nfsr = s.nfsr.shift(uint32(u)) 458 | 459 | x := nn0 >> 2 460 | x ^= nn0 >> 15 461 | x ^= nn1 >> 4 462 | x ^= nn1 >> 13 463 | x ^= nn2 464 | x ^= nn2 >> 9 465 | x ^= nn2 >> 25 466 | x ^= ln2 >> 29 467 | x ^= (nn0 >> 12) & (ln0 >> 8) 468 | x ^= (ln0 >> 13) & (ln0 >> 20) 469 | x ^= (nn2 >> 31) & (ln1 >> 10) 470 | x ^= (ln1 >> 28) & (ln2 >> 15) 471 | x ^= (nn0 >> 12) & (nn2 >> 31) & (ln2 >> 30) 472 | return uint32(x) 473 | } 474 | 475 | func accumulateGeneric(reg, acc uint64, ms, pt uint16) (reg1, acc1 uint64) { 476 | // accumulateGeneric has this signature because it allows the 477 | // function to be inlined. 478 | var acctmp uint64 479 | regtmp := uint32(ms) << 16 480 | for i := 0; i < 16; i++ { 481 | acc ^= reg & -uint64(pt&1) 482 | reg >>= 1 483 | 484 | acctmp ^= uint64(regtmp) & -uint64(pt&1) 485 | regtmp >>= 1 486 | 487 | pt >>= 1 488 | } 489 | return reg | uint64(ms)<<48, acc ^ acctmp<<48 490 | } 491 | 492 | func (s *state) accumulate8(ms, pt uint8) { 493 | var acctmp uint8 494 | regtmp := uint16(ms) << 8 495 | reg := s.reg 496 | acc := s.acc 497 | 498 | for i := 0; i < 8; i++ { 499 | mask := -uint64(pt & 1) 500 | acc ^= reg & mask 501 | reg >>= 1 502 | 503 | acctmp ^= uint8(regtmp) & uint8(mask) 504 | regtmp >>= 1 505 | 506 | pt >>= 1 507 | } 508 | 509 | s.reg = reg | uint64(ms)<<56 510 | s.acc = acc ^ uint64(acctmp)<<56 511 | } 512 | 513 | func getmb(num uint32) uint16 { 514 | const ( 515 | mvo0 = 0x22222222 516 | mvo1 = 0x18181818 517 | mvo2 = 0x07800780 518 | mvo3 = 0x007f8000 519 | mvo4 = 0x80000000 520 | ) 521 | 522 | // 0xAAA... extracts the odd MAC bits, LSB first. 523 | x := uint32(num & 0xAAAAAAAA) 524 | // Inlining the "t = mvoX" assignments allows the compiler to 525 | // inline getmb itself, because as of Go 1.16 the compiler 526 | // still judges the complexity of a function based on the 527 | // number of *lexical* statements. 528 | x = (x ^ (x & mvo0)) | (x&mvo0)>>1 529 | x = (x ^ (x & mvo1)) | (x&mvo1)>>2 530 | x = (x ^ (x & mvo2)) | (x&mvo2)>>4 531 | x = (x ^ (x & mvo3)) | (x&mvo3)>>8 532 | x = (x ^ (x & mvo4)) | (x&mvo4)>>16 533 | return uint16(x) 534 | } 535 | 536 | func getkb(num uint32) uint16 { 537 | const ( 538 | mve0 = 0x44444444 539 | mve1 = 0x30303030 540 | mve2 = 0x0f000f00 541 | mve3 = 0x00ff0000 542 | ) 543 | 544 | var t uint32 545 | // 0x555... extracts the even key bits, LSB first. 546 | x := uint32(num & 0x55555555) 547 | t = x & mve0 548 | x = (x ^ t) | (t >> 1) 549 | t = x & mve1 550 | x = (x ^ t) | (t >> 2) 551 | t = x & mve2 552 | x = (x ^ t) | (t >> 4) 553 | t = x & mve3 554 | x = (x ^ t) | (t >> 8) 555 | return uint16(x) 556 | } 557 | 558 | // shortInt is the largest allowed integer for DER's "short" 559 | // encoding. 560 | const shortInt = 127 561 | 562 | // der is a DER-encoded integer using the definite form. 563 | type der [10]byte 564 | 565 | // len returns the number of bytes used in d. 566 | func (d der) len() int { 567 | // d[0] encodes the number of following bytes, so add one. 568 | return int(d[0]&^0x80) + 1 569 | } 570 | 571 | // encode encodes the length x using DER's definite form for 572 | // x > shortInt. 573 | // 574 | // encode returns an even number of bytes to make the call site 575 | // easier. 576 | func encode(x int) (d der) { 577 | n := (bits.Len(uint(x)) + 7) / 8 578 | d[0] = byte(0x80 | n) 579 | for i := n; i > 0; i-- { 580 | d[i] = byte(n) 581 | n >>= 8 582 | } 583 | return d 584 | } 585 | 586 | // lfsr is a 128-bit LFSR. 587 | // 588 | // New input is added in the high 32 bits, shifting old bits off 589 | // the front. 590 | type lfsr struct { 591 | lo, hi uint64 592 | } 593 | 594 | type nfsr = lfsr 595 | 596 | // shift shifts off 32 low bits and replaces the high bits with 597 | // x: 598 | // 599 | // u = (u >> 32) | (x << 96) 600 | // 601 | func (r lfsr) shift(x uint32) lfsr { 602 | const s = 32 603 | lo := r.lo>>s | r.hi<<(64-s) 604 | hi := r.hi>>s | uint64(x)<>32) ^ x 612 | hi := uint64(hi32)<<32 | r.hi&mask 613 | return lfsr{r.lo, hi} 614 | } 615 | 616 | // words returns the state of the LFSR as 64-bit words. 617 | // 618 | // Each word is offset 32 bits: 619 | // 620 | // u0: [0, 64) 621 | // u1: [32, 96) 622 | // u2: [64, 128) 623 | // u3: [96, 128) 624 | // 625 | func (r lfsr) words() (u0, u1, u2, u3 uint64) { 626 | u0 = r.lo // 0,1 627 | u1 = r.lo>>32 | r.hi<<32 // 1,2 628 | u2 = r.hi // 2,3 629 | u3 = r.hi >> 32 // 3,x 630 | return 631 | } 632 | 633 | func (r lfsr) String() string { 634 | var b strings.Builder 635 | b.WriteByte('[') 636 | fmt.Fprintf(&b, "%#x ", uint32(r.lo)) 637 | fmt.Fprintf(&b, "%#x ", uint32(r.lo>>32)) 638 | fmt.Fprintf(&b, "%#x ", uint32(r.hi)) 639 | fmt.Fprintf(&b, "%#x", uint32(r.hi>>32)) 640 | b.WriteByte(']') 641 | return b.String() 642 | } 643 | -------------------------------------------------------------------------------- /ascon/ascon_amd64.s: -------------------------------------------------------------------------------- 1 | // Code generated by command: go run asm.go -out out/ascon_amd64.s -stubs out/stub_amd64.go -pkg ascon. DO NOT EDIT. 2 | 3 | // +build gc,!purego 4 | 5 | #include "textflag.h" 6 | 7 | // func p12(s *state) 8 | TEXT ·p12(SB), NOSPLIT, $0-8 9 | MOVQ s+0(FP), AX 10 | MOVQ (AX), CX 11 | MOVQ 8(AX), DX 12 | MOVQ 16(AX), BX 13 | MOVQ 24(AX), SI 14 | MOVQ 32(AX), DI 15 | 16 | // Start round 1 17 | // Round constant 18 | XORQ $0x000000f0, BX 19 | 20 | // Substitution 21 | XORQ DI, CX 22 | XORQ SI, DI 23 | XORQ DX, BX 24 | 25 | // Keccak S-box 26 | MOVQ DX, R9 27 | NOTQ R9 28 | MOVQ BX, R8 29 | ANDQ R9, R8 30 | XORQ CX, R8 31 | MOVQ BX, R10 32 | NOTQ R10 33 | MOVQ SI, R9 34 | ANDQ R10, R9 35 | XORQ DX, R9 36 | MOVQ SI, R11 37 | NOTQ R11 38 | MOVQ DI, R10 39 | ANDQ R11, R10 40 | XORQ BX, R10 41 | MOVQ DI, BX 42 | NOTQ BX 43 | MOVQ CX, R11 44 | ANDQ BX, R11 45 | XORQ SI, R11 46 | NOTQ CX 47 | MOVQ DX, R12 48 | ANDQ CX, R12 49 | XORQ DI, R12 50 | 51 | // Substituton 52 | XORQ R8, R9 53 | XORQ R12, R8 54 | XORQ R10, R11 55 | NOTQ R10 56 | 57 | // Linear diffusion 58 | MOVQ R8, CX 59 | RORQ $0x13, CX 60 | XORQ R8, CX 61 | MOVQ R8, DX 62 | RORQ $0x1c, DX 63 | XORQ DX, CX 64 | MOVQ R9, DX 65 | RORQ $0x3d, DX 66 | XORQ R9, DX 67 | MOVQ R9, BX 68 | RORQ $0x27, BX 69 | XORQ BX, DX 70 | MOVQ R10, BX 71 | RORQ $0x01, BX 72 | XORQ R10, BX 73 | MOVQ R10, SI 74 | RORQ $0x06, SI 75 | XORQ SI, BX 76 | MOVQ R11, SI 77 | RORQ $0x0a, SI 78 | XORQ R11, SI 79 | MOVQ R11, DI 80 | RORQ $0x11, DI 81 | XORQ DI, SI 82 | MOVQ R12, DI 83 | RORQ $0x07, DI 84 | XORQ R12, DI 85 | MOVQ R12, R8 86 | RORQ $0x29, R8 87 | XORQ R8, DI 88 | 89 | // End round 1 90 | 91 | // Start round 2 92 | // Round constant 93 | XORQ $0x000000e1, BX 94 | 95 | // Substitution 96 | XORQ DI, CX 97 | XORQ SI, DI 98 | XORQ DX, BX 99 | 100 | // Keccak S-box 101 | MOVQ DX, R9 102 | NOTQ R9 103 | MOVQ BX, R8 104 | ANDQ R9, R8 105 | XORQ CX, R8 106 | MOVQ BX, R10 107 | NOTQ R10 108 | MOVQ SI, R9 109 | ANDQ R10, R9 110 | XORQ DX, R9 111 | MOVQ SI, R11 112 | NOTQ R11 113 | MOVQ DI, R10 114 | ANDQ R11, R10 115 | XORQ BX, R10 116 | MOVQ DI, BX 117 | NOTQ BX 118 | MOVQ CX, R11 119 | ANDQ BX, R11 120 | XORQ SI, R11 121 | NOTQ CX 122 | MOVQ DX, R12 123 | ANDQ CX, R12 124 | XORQ DI, R12 125 | 126 | // Substituton 127 | XORQ R8, R9 128 | XORQ R12, R8 129 | XORQ R10, R11 130 | NOTQ R10 131 | 132 | // Linear diffusion 133 | MOVQ R8, CX 134 | RORQ $0x13, CX 135 | XORQ R8, CX 136 | MOVQ R8, DX 137 | RORQ $0x1c, DX 138 | XORQ DX, CX 139 | MOVQ R9, DX 140 | RORQ $0x3d, DX 141 | XORQ R9, DX 142 | MOVQ R9, BX 143 | RORQ $0x27, BX 144 | XORQ BX, DX 145 | MOVQ R10, BX 146 | RORQ $0x01, BX 147 | XORQ R10, BX 148 | MOVQ R10, SI 149 | RORQ $0x06, SI 150 | XORQ SI, BX 151 | MOVQ R11, SI 152 | RORQ $0x0a, SI 153 | XORQ R11, SI 154 | MOVQ R11, DI 155 | RORQ $0x11, DI 156 | XORQ DI, SI 157 | MOVQ R12, DI 158 | RORQ $0x07, DI 159 | XORQ R12, DI 160 | MOVQ R12, R8 161 | RORQ $0x29, R8 162 | XORQ R8, DI 163 | 164 | // End round 2 165 | 166 | // Start round 3 167 | // Round constant 168 | XORQ $0x000000d2, BX 169 | 170 | // Substitution 171 | XORQ DI, CX 172 | XORQ SI, DI 173 | XORQ DX, BX 174 | 175 | // Keccak S-box 176 | MOVQ DX, R9 177 | NOTQ R9 178 | MOVQ BX, R8 179 | ANDQ R9, R8 180 | XORQ CX, R8 181 | MOVQ BX, R10 182 | NOTQ R10 183 | MOVQ SI, R9 184 | ANDQ R10, R9 185 | XORQ DX, R9 186 | MOVQ SI, R11 187 | NOTQ R11 188 | MOVQ DI, R10 189 | ANDQ R11, R10 190 | XORQ BX, R10 191 | MOVQ DI, BX 192 | NOTQ BX 193 | MOVQ CX, R11 194 | ANDQ BX, R11 195 | XORQ SI, R11 196 | NOTQ CX 197 | MOVQ DX, R12 198 | ANDQ CX, R12 199 | XORQ DI, R12 200 | 201 | // Substituton 202 | XORQ R8, R9 203 | XORQ R12, R8 204 | XORQ R10, R11 205 | NOTQ R10 206 | 207 | // Linear diffusion 208 | MOVQ R8, CX 209 | RORQ $0x13, CX 210 | XORQ R8, CX 211 | MOVQ R8, DX 212 | RORQ $0x1c, DX 213 | XORQ DX, CX 214 | MOVQ R9, DX 215 | RORQ $0x3d, DX 216 | XORQ R9, DX 217 | MOVQ R9, BX 218 | RORQ $0x27, BX 219 | XORQ BX, DX 220 | MOVQ R10, BX 221 | RORQ $0x01, BX 222 | XORQ R10, BX 223 | MOVQ R10, SI 224 | RORQ $0x06, SI 225 | XORQ SI, BX 226 | MOVQ R11, SI 227 | RORQ $0x0a, SI 228 | XORQ R11, SI 229 | MOVQ R11, DI 230 | RORQ $0x11, DI 231 | XORQ DI, SI 232 | MOVQ R12, DI 233 | RORQ $0x07, DI 234 | XORQ R12, DI 235 | MOVQ R12, R8 236 | RORQ $0x29, R8 237 | XORQ R8, DI 238 | 239 | // End round 3 240 | 241 | // Start round 4 242 | // Round constant 243 | XORQ $0x000000c3, BX 244 | 245 | // Substitution 246 | XORQ DI, CX 247 | XORQ SI, DI 248 | XORQ DX, BX 249 | 250 | // Keccak S-box 251 | MOVQ DX, R9 252 | NOTQ R9 253 | MOVQ BX, R8 254 | ANDQ R9, R8 255 | XORQ CX, R8 256 | MOVQ BX, R10 257 | NOTQ R10 258 | MOVQ SI, R9 259 | ANDQ R10, R9 260 | XORQ DX, R9 261 | MOVQ SI, R11 262 | NOTQ R11 263 | MOVQ DI, R10 264 | ANDQ R11, R10 265 | XORQ BX, R10 266 | MOVQ DI, BX 267 | NOTQ BX 268 | MOVQ CX, R11 269 | ANDQ BX, R11 270 | XORQ SI, R11 271 | NOTQ CX 272 | MOVQ DX, R12 273 | ANDQ CX, R12 274 | XORQ DI, R12 275 | 276 | // Substituton 277 | XORQ R8, R9 278 | XORQ R12, R8 279 | XORQ R10, R11 280 | NOTQ R10 281 | 282 | // Linear diffusion 283 | MOVQ R8, CX 284 | RORQ $0x13, CX 285 | XORQ R8, CX 286 | MOVQ R8, DX 287 | RORQ $0x1c, DX 288 | XORQ DX, CX 289 | MOVQ R9, DX 290 | RORQ $0x3d, DX 291 | XORQ R9, DX 292 | MOVQ R9, BX 293 | RORQ $0x27, BX 294 | XORQ BX, DX 295 | MOVQ R10, BX 296 | RORQ $0x01, BX 297 | XORQ R10, BX 298 | MOVQ R10, SI 299 | RORQ $0x06, SI 300 | XORQ SI, BX 301 | MOVQ R11, SI 302 | RORQ $0x0a, SI 303 | XORQ R11, SI 304 | MOVQ R11, DI 305 | RORQ $0x11, DI 306 | XORQ DI, SI 307 | MOVQ R12, DI 308 | RORQ $0x07, DI 309 | XORQ R12, DI 310 | MOVQ R12, R8 311 | RORQ $0x29, R8 312 | XORQ R8, DI 313 | 314 | // End round 4 315 | 316 | // Start round 5 317 | // Round constant 318 | XORQ $0x000000b4, BX 319 | 320 | // Substitution 321 | XORQ DI, CX 322 | XORQ SI, DI 323 | XORQ DX, BX 324 | 325 | // Keccak S-box 326 | MOVQ DX, R9 327 | NOTQ R9 328 | MOVQ BX, R8 329 | ANDQ R9, R8 330 | XORQ CX, R8 331 | MOVQ BX, R10 332 | NOTQ R10 333 | MOVQ SI, R9 334 | ANDQ R10, R9 335 | XORQ DX, R9 336 | MOVQ SI, R11 337 | NOTQ R11 338 | MOVQ DI, R10 339 | ANDQ R11, R10 340 | XORQ BX, R10 341 | MOVQ DI, BX 342 | NOTQ BX 343 | MOVQ CX, R11 344 | ANDQ BX, R11 345 | XORQ SI, R11 346 | NOTQ CX 347 | MOVQ DX, R12 348 | ANDQ CX, R12 349 | XORQ DI, R12 350 | 351 | // Substituton 352 | XORQ R8, R9 353 | XORQ R12, R8 354 | XORQ R10, R11 355 | NOTQ R10 356 | 357 | // Linear diffusion 358 | MOVQ R8, CX 359 | RORQ $0x13, CX 360 | XORQ R8, CX 361 | MOVQ R8, DX 362 | RORQ $0x1c, DX 363 | XORQ DX, CX 364 | MOVQ R9, DX 365 | RORQ $0x3d, DX 366 | XORQ R9, DX 367 | MOVQ R9, BX 368 | RORQ $0x27, BX 369 | XORQ BX, DX 370 | MOVQ R10, BX 371 | RORQ $0x01, BX 372 | XORQ R10, BX 373 | MOVQ R10, SI 374 | RORQ $0x06, SI 375 | XORQ SI, BX 376 | MOVQ R11, SI 377 | RORQ $0x0a, SI 378 | XORQ R11, SI 379 | MOVQ R11, DI 380 | RORQ $0x11, DI 381 | XORQ DI, SI 382 | MOVQ R12, DI 383 | RORQ $0x07, DI 384 | XORQ R12, DI 385 | MOVQ R12, R8 386 | RORQ $0x29, R8 387 | XORQ R8, DI 388 | 389 | // End round 5 390 | 391 | // Start round 6 392 | // Round constant 393 | XORQ $0x000000a5, BX 394 | 395 | // Substitution 396 | XORQ DI, CX 397 | XORQ SI, DI 398 | XORQ DX, BX 399 | 400 | // Keccak S-box 401 | MOVQ DX, R9 402 | NOTQ R9 403 | MOVQ BX, R8 404 | ANDQ R9, R8 405 | XORQ CX, R8 406 | MOVQ BX, R10 407 | NOTQ R10 408 | MOVQ SI, R9 409 | ANDQ R10, R9 410 | XORQ DX, R9 411 | MOVQ SI, R11 412 | NOTQ R11 413 | MOVQ DI, R10 414 | ANDQ R11, R10 415 | XORQ BX, R10 416 | MOVQ DI, BX 417 | NOTQ BX 418 | MOVQ CX, R11 419 | ANDQ BX, R11 420 | XORQ SI, R11 421 | NOTQ CX 422 | MOVQ DX, R12 423 | ANDQ CX, R12 424 | XORQ DI, R12 425 | 426 | // Substituton 427 | XORQ R8, R9 428 | XORQ R12, R8 429 | XORQ R10, R11 430 | NOTQ R10 431 | 432 | // Linear diffusion 433 | MOVQ R8, CX 434 | RORQ $0x13, CX 435 | XORQ R8, CX 436 | MOVQ R8, DX 437 | RORQ $0x1c, DX 438 | XORQ DX, CX 439 | MOVQ R9, DX 440 | RORQ $0x3d, DX 441 | XORQ R9, DX 442 | MOVQ R9, BX 443 | RORQ $0x27, BX 444 | XORQ BX, DX 445 | MOVQ R10, BX 446 | RORQ $0x01, BX 447 | XORQ R10, BX 448 | MOVQ R10, SI 449 | RORQ $0x06, SI 450 | XORQ SI, BX 451 | MOVQ R11, SI 452 | RORQ $0x0a, SI 453 | XORQ R11, SI 454 | MOVQ R11, DI 455 | RORQ $0x11, DI 456 | XORQ DI, SI 457 | MOVQ R12, DI 458 | RORQ $0x07, DI 459 | XORQ R12, DI 460 | MOVQ R12, R8 461 | RORQ $0x29, R8 462 | XORQ R8, DI 463 | 464 | // End round 6 465 | 466 | // Start round 7 467 | // Round constant 468 | XORQ $0x00000096, BX 469 | 470 | // Substitution 471 | XORQ DI, CX 472 | XORQ SI, DI 473 | XORQ DX, BX 474 | 475 | // Keccak S-box 476 | MOVQ DX, R9 477 | NOTQ R9 478 | MOVQ BX, R8 479 | ANDQ R9, R8 480 | XORQ CX, R8 481 | MOVQ BX, R10 482 | NOTQ R10 483 | MOVQ SI, R9 484 | ANDQ R10, R9 485 | XORQ DX, R9 486 | MOVQ SI, R11 487 | NOTQ R11 488 | MOVQ DI, R10 489 | ANDQ R11, R10 490 | XORQ BX, R10 491 | MOVQ DI, BX 492 | NOTQ BX 493 | MOVQ CX, R11 494 | ANDQ BX, R11 495 | XORQ SI, R11 496 | NOTQ CX 497 | MOVQ DX, R12 498 | ANDQ CX, R12 499 | XORQ DI, R12 500 | 501 | // Substituton 502 | XORQ R8, R9 503 | XORQ R12, R8 504 | XORQ R10, R11 505 | NOTQ R10 506 | 507 | // Linear diffusion 508 | MOVQ R8, CX 509 | RORQ $0x13, CX 510 | XORQ R8, CX 511 | MOVQ R8, DX 512 | RORQ $0x1c, DX 513 | XORQ DX, CX 514 | MOVQ R9, DX 515 | RORQ $0x3d, DX 516 | XORQ R9, DX 517 | MOVQ R9, BX 518 | RORQ $0x27, BX 519 | XORQ BX, DX 520 | MOVQ R10, BX 521 | RORQ $0x01, BX 522 | XORQ R10, BX 523 | MOVQ R10, SI 524 | RORQ $0x06, SI 525 | XORQ SI, BX 526 | MOVQ R11, SI 527 | RORQ $0x0a, SI 528 | XORQ R11, SI 529 | MOVQ R11, DI 530 | RORQ $0x11, DI 531 | XORQ DI, SI 532 | MOVQ R12, DI 533 | RORQ $0x07, DI 534 | XORQ R12, DI 535 | MOVQ R12, R8 536 | RORQ $0x29, R8 537 | XORQ R8, DI 538 | 539 | // End round 7 540 | 541 | // Start round 8 542 | // Round constant 543 | XORQ $0x00000087, BX 544 | 545 | // Substitution 546 | XORQ DI, CX 547 | XORQ SI, DI 548 | XORQ DX, BX 549 | 550 | // Keccak S-box 551 | MOVQ DX, R9 552 | NOTQ R9 553 | MOVQ BX, R8 554 | ANDQ R9, R8 555 | XORQ CX, R8 556 | MOVQ BX, R10 557 | NOTQ R10 558 | MOVQ SI, R9 559 | ANDQ R10, R9 560 | XORQ DX, R9 561 | MOVQ SI, R11 562 | NOTQ R11 563 | MOVQ DI, R10 564 | ANDQ R11, R10 565 | XORQ BX, R10 566 | MOVQ DI, BX 567 | NOTQ BX 568 | MOVQ CX, R11 569 | ANDQ BX, R11 570 | XORQ SI, R11 571 | NOTQ CX 572 | MOVQ DX, R12 573 | ANDQ CX, R12 574 | XORQ DI, R12 575 | 576 | // Substituton 577 | XORQ R8, R9 578 | XORQ R12, R8 579 | XORQ R10, R11 580 | NOTQ R10 581 | 582 | // Linear diffusion 583 | MOVQ R8, CX 584 | RORQ $0x13, CX 585 | XORQ R8, CX 586 | MOVQ R8, DX 587 | RORQ $0x1c, DX 588 | XORQ DX, CX 589 | MOVQ R9, DX 590 | RORQ $0x3d, DX 591 | XORQ R9, DX 592 | MOVQ R9, BX 593 | RORQ $0x27, BX 594 | XORQ BX, DX 595 | MOVQ R10, BX 596 | RORQ $0x01, BX 597 | XORQ R10, BX 598 | MOVQ R10, SI 599 | RORQ $0x06, SI 600 | XORQ SI, BX 601 | MOVQ R11, SI 602 | RORQ $0x0a, SI 603 | XORQ R11, SI 604 | MOVQ R11, DI 605 | RORQ $0x11, DI 606 | XORQ DI, SI 607 | MOVQ R12, DI 608 | RORQ $0x07, DI 609 | XORQ R12, DI 610 | MOVQ R12, R8 611 | RORQ $0x29, R8 612 | XORQ R8, DI 613 | 614 | // End round 8 615 | 616 | // Start round 9 617 | // Round constant 618 | XORQ $0x00000078, BX 619 | 620 | // Substitution 621 | XORQ DI, CX 622 | XORQ SI, DI 623 | XORQ DX, BX 624 | 625 | // Keccak S-box 626 | MOVQ DX, R9 627 | NOTQ R9 628 | MOVQ BX, R8 629 | ANDQ R9, R8 630 | XORQ CX, R8 631 | MOVQ BX, R10 632 | NOTQ R10 633 | MOVQ SI, R9 634 | ANDQ R10, R9 635 | XORQ DX, R9 636 | MOVQ SI, R11 637 | NOTQ R11 638 | MOVQ DI, R10 639 | ANDQ R11, R10 640 | XORQ BX, R10 641 | MOVQ DI, BX 642 | NOTQ BX 643 | MOVQ CX, R11 644 | ANDQ BX, R11 645 | XORQ SI, R11 646 | NOTQ CX 647 | MOVQ DX, R12 648 | ANDQ CX, R12 649 | XORQ DI, R12 650 | 651 | // Substituton 652 | XORQ R8, R9 653 | XORQ R12, R8 654 | XORQ R10, R11 655 | NOTQ R10 656 | 657 | // Linear diffusion 658 | MOVQ R8, CX 659 | RORQ $0x13, CX 660 | XORQ R8, CX 661 | MOVQ R8, DX 662 | RORQ $0x1c, DX 663 | XORQ DX, CX 664 | MOVQ R9, DX 665 | RORQ $0x3d, DX 666 | XORQ R9, DX 667 | MOVQ R9, BX 668 | RORQ $0x27, BX 669 | XORQ BX, DX 670 | MOVQ R10, BX 671 | RORQ $0x01, BX 672 | XORQ R10, BX 673 | MOVQ R10, SI 674 | RORQ $0x06, SI 675 | XORQ SI, BX 676 | MOVQ R11, SI 677 | RORQ $0x0a, SI 678 | XORQ R11, SI 679 | MOVQ R11, DI 680 | RORQ $0x11, DI 681 | XORQ DI, SI 682 | MOVQ R12, DI 683 | RORQ $0x07, DI 684 | XORQ R12, DI 685 | MOVQ R12, R8 686 | RORQ $0x29, R8 687 | XORQ R8, DI 688 | 689 | // End round 9 690 | 691 | // Start round 10 692 | // Round constant 693 | XORQ $0x00000069, BX 694 | 695 | // Substitution 696 | XORQ DI, CX 697 | XORQ SI, DI 698 | XORQ DX, BX 699 | 700 | // Keccak S-box 701 | MOVQ DX, R9 702 | NOTQ R9 703 | MOVQ BX, R8 704 | ANDQ R9, R8 705 | XORQ CX, R8 706 | MOVQ BX, R10 707 | NOTQ R10 708 | MOVQ SI, R9 709 | ANDQ R10, R9 710 | XORQ DX, R9 711 | MOVQ SI, R11 712 | NOTQ R11 713 | MOVQ DI, R10 714 | ANDQ R11, R10 715 | XORQ BX, R10 716 | MOVQ DI, BX 717 | NOTQ BX 718 | MOVQ CX, R11 719 | ANDQ BX, R11 720 | XORQ SI, R11 721 | NOTQ CX 722 | MOVQ DX, R12 723 | ANDQ CX, R12 724 | XORQ DI, R12 725 | 726 | // Substituton 727 | XORQ R8, R9 728 | XORQ R12, R8 729 | XORQ R10, R11 730 | NOTQ R10 731 | 732 | // Linear diffusion 733 | MOVQ R8, CX 734 | RORQ $0x13, CX 735 | XORQ R8, CX 736 | MOVQ R8, DX 737 | RORQ $0x1c, DX 738 | XORQ DX, CX 739 | MOVQ R9, DX 740 | RORQ $0x3d, DX 741 | XORQ R9, DX 742 | MOVQ R9, BX 743 | RORQ $0x27, BX 744 | XORQ BX, DX 745 | MOVQ R10, BX 746 | RORQ $0x01, BX 747 | XORQ R10, BX 748 | MOVQ R10, SI 749 | RORQ $0x06, SI 750 | XORQ SI, BX 751 | MOVQ R11, SI 752 | RORQ $0x0a, SI 753 | XORQ R11, SI 754 | MOVQ R11, DI 755 | RORQ $0x11, DI 756 | XORQ DI, SI 757 | MOVQ R12, DI 758 | RORQ $0x07, DI 759 | XORQ R12, DI 760 | MOVQ R12, R8 761 | RORQ $0x29, R8 762 | XORQ R8, DI 763 | 764 | // End round 10 765 | 766 | // Start round 11 767 | // Round constant 768 | XORQ $0x0000005a, BX 769 | 770 | // Substitution 771 | XORQ DI, CX 772 | XORQ SI, DI 773 | XORQ DX, BX 774 | 775 | // Keccak S-box 776 | MOVQ DX, R9 777 | NOTQ R9 778 | MOVQ BX, R8 779 | ANDQ R9, R8 780 | XORQ CX, R8 781 | MOVQ BX, R10 782 | NOTQ R10 783 | MOVQ SI, R9 784 | ANDQ R10, R9 785 | XORQ DX, R9 786 | MOVQ SI, R11 787 | NOTQ R11 788 | MOVQ DI, R10 789 | ANDQ R11, R10 790 | XORQ BX, R10 791 | MOVQ DI, BX 792 | NOTQ BX 793 | MOVQ CX, R11 794 | ANDQ BX, R11 795 | XORQ SI, R11 796 | NOTQ CX 797 | MOVQ DX, R12 798 | ANDQ CX, R12 799 | XORQ DI, R12 800 | 801 | // Substituton 802 | XORQ R8, R9 803 | XORQ R12, R8 804 | XORQ R10, R11 805 | NOTQ R10 806 | 807 | // Linear diffusion 808 | MOVQ R8, CX 809 | RORQ $0x13, CX 810 | XORQ R8, CX 811 | MOVQ R8, DX 812 | RORQ $0x1c, DX 813 | XORQ DX, CX 814 | MOVQ R9, DX 815 | RORQ $0x3d, DX 816 | XORQ R9, DX 817 | MOVQ R9, BX 818 | RORQ $0x27, BX 819 | XORQ BX, DX 820 | MOVQ R10, BX 821 | RORQ $0x01, BX 822 | XORQ R10, BX 823 | MOVQ R10, SI 824 | RORQ $0x06, SI 825 | XORQ SI, BX 826 | MOVQ R11, SI 827 | RORQ $0x0a, SI 828 | XORQ R11, SI 829 | MOVQ R11, DI 830 | RORQ $0x11, DI 831 | XORQ DI, SI 832 | MOVQ R12, DI 833 | RORQ $0x07, DI 834 | XORQ R12, DI 835 | MOVQ R12, R8 836 | RORQ $0x29, R8 837 | XORQ R8, DI 838 | 839 | // End round 11 840 | 841 | // Start round 12 842 | // Round constant 843 | XORQ $0x0000004b, BX 844 | 845 | // Substitution 846 | XORQ DI, CX 847 | XORQ SI, DI 848 | XORQ DX, BX 849 | 850 | // Keccak S-box 851 | MOVQ DX, R9 852 | NOTQ R9 853 | MOVQ BX, R8 854 | ANDQ R9, R8 855 | XORQ CX, R8 856 | MOVQ BX, R10 857 | NOTQ R10 858 | MOVQ SI, R9 859 | ANDQ R10, R9 860 | XORQ DX, R9 861 | MOVQ SI, R11 862 | NOTQ R11 863 | MOVQ DI, R10 864 | ANDQ R11, R10 865 | XORQ BX, R10 866 | MOVQ DI, BX 867 | NOTQ BX 868 | MOVQ CX, R11 869 | ANDQ BX, R11 870 | XORQ SI, R11 871 | NOTQ CX 872 | MOVQ DX, R12 873 | ANDQ CX, R12 874 | XORQ DI, R12 875 | 876 | // Substituton 877 | XORQ R8, R9 878 | XORQ R12, R8 879 | XORQ R10, R11 880 | NOTQ R10 881 | 882 | // Linear diffusion 883 | MOVQ R8, CX 884 | RORQ $0x13, CX 885 | XORQ R8, CX 886 | MOVQ R8, DX 887 | RORQ $0x1c, DX 888 | XORQ DX, CX 889 | MOVQ R9, DX 890 | RORQ $0x3d, DX 891 | XORQ R9, DX 892 | MOVQ R9, BX 893 | RORQ $0x27, BX 894 | XORQ BX, DX 895 | MOVQ R10, BX 896 | RORQ $0x01, BX 897 | XORQ R10, BX 898 | MOVQ R10, SI 899 | RORQ $0x06, SI 900 | XORQ SI, BX 901 | MOVQ R11, SI 902 | RORQ $0x0a, SI 903 | XORQ R11, SI 904 | MOVQ R11, DI 905 | RORQ $0x11, DI 906 | XORQ DI, SI 907 | MOVQ R12, DI 908 | RORQ $0x07, DI 909 | XORQ R12, DI 910 | MOVQ R12, R8 911 | RORQ $0x29, R8 912 | XORQ R8, DI 913 | 914 | // End round 12 915 | 916 | MOVQ CX, (AX) 917 | MOVQ DX, 8(AX) 918 | MOVQ BX, 16(AX) 919 | MOVQ SI, 24(AX) 920 | MOVQ DI, 32(AX) 921 | RET 922 | 923 | // func p8(s *state) 924 | TEXT ·p8(SB), NOSPLIT, $0-8 925 | MOVQ s+0(FP), AX 926 | MOVQ (AX), CX 927 | MOVQ 8(AX), DX 928 | MOVQ 16(AX), BX 929 | MOVQ 24(AX), SI 930 | MOVQ 32(AX), DI 931 | 932 | // Start round 1 933 | // Round constant 934 | XORQ $0x000000b4, BX 935 | 936 | // Substitution 937 | XORQ DI, CX 938 | XORQ SI, DI 939 | XORQ DX, BX 940 | 941 | // Keccak S-box 942 | MOVQ DX, R9 943 | NOTQ R9 944 | MOVQ BX, R8 945 | ANDQ R9, R8 946 | XORQ CX, R8 947 | MOVQ BX, R10 948 | NOTQ R10 949 | MOVQ SI, R9 950 | ANDQ R10, R9 951 | XORQ DX, R9 952 | MOVQ SI, R11 953 | NOTQ R11 954 | MOVQ DI, R10 955 | ANDQ R11, R10 956 | XORQ BX, R10 957 | MOVQ DI, BX 958 | NOTQ BX 959 | MOVQ CX, R11 960 | ANDQ BX, R11 961 | XORQ SI, R11 962 | NOTQ CX 963 | MOVQ DX, R12 964 | ANDQ CX, R12 965 | XORQ DI, R12 966 | 967 | // Substituton 968 | XORQ R8, R9 969 | XORQ R12, R8 970 | XORQ R10, R11 971 | NOTQ R10 972 | 973 | // Linear diffusion 974 | MOVQ R8, CX 975 | RORQ $0x13, CX 976 | XORQ R8, CX 977 | MOVQ R8, DX 978 | RORQ $0x1c, DX 979 | XORQ DX, CX 980 | MOVQ R9, DX 981 | RORQ $0x3d, DX 982 | XORQ R9, DX 983 | MOVQ R9, BX 984 | RORQ $0x27, BX 985 | XORQ BX, DX 986 | MOVQ R10, BX 987 | RORQ $0x01, BX 988 | XORQ R10, BX 989 | MOVQ R10, SI 990 | RORQ $0x06, SI 991 | XORQ SI, BX 992 | MOVQ R11, SI 993 | RORQ $0x0a, SI 994 | XORQ R11, SI 995 | MOVQ R11, DI 996 | RORQ $0x11, DI 997 | XORQ DI, SI 998 | MOVQ R12, DI 999 | RORQ $0x07, DI 1000 | XORQ R12, DI 1001 | MOVQ R12, R8 1002 | RORQ $0x29, R8 1003 | XORQ R8, DI 1004 | 1005 | // End round 1 1006 | 1007 | // Start round 2 1008 | // Round constant 1009 | XORQ $0x000000a5, BX 1010 | 1011 | // Substitution 1012 | XORQ DI, CX 1013 | XORQ SI, DI 1014 | XORQ DX, BX 1015 | 1016 | // Keccak S-box 1017 | MOVQ DX, R9 1018 | NOTQ R9 1019 | MOVQ BX, R8 1020 | ANDQ R9, R8 1021 | XORQ CX, R8 1022 | MOVQ BX, R10 1023 | NOTQ R10 1024 | MOVQ SI, R9 1025 | ANDQ R10, R9 1026 | XORQ DX, R9 1027 | MOVQ SI, R11 1028 | NOTQ R11 1029 | MOVQ DI, R10 1030 | ANDQ R11, R10 1031 | XORQ BX, R10 1032 | MOVQ DI, BX 1033 | NOTQ BX 1034 | MOVQ CX, R11 1035 | ANDQ BX, R11 1036 | XORQ SI, R11 1037 | NOTQ CX 1038 | MOVQ DX, R12 1039 | ANDQ CX, R12 1040 | XORQ DI, R12 1041 | 1042 | // Substituton 1043 | XORQ R8, R9 1044 | XORQ R12, R8 1045 | XORQ R10, R11 1046 | NOTQ R10 1047 | 1048 | // Linear diffusion 1049 | MOVQ R8, CX 1050 | RORQ $0x13, CX 1051 | XORQ R8, CX 1052 | MOVQ R8, DX 1053 | RORQ $0x1c, DX 1054 | XORQ DX, CX 1055 | MOVQ R9, DX 1056 | RORQ $0x3d, DX 1057 | XORQ R9, DX 1058 | MOVQ R9, BX 1059 | RORQ $0x27, BX 1060 | XORQ BX, DX 1061 | MOVQ R10, BX 1062 | RORQ $0x01, BX 1063 | XORQ R10, BX 1064 | MOVQ R10, SI 1065 | RORQ $0x06, SI 1066 | XORQ SI, BX 1067 | MOVQ R11, SI 1068 | RORQ $0x0a, SI 1069 | XORQ R11, SI 1070 | MOVQ R11, DI 1071 | RORQ $0x11, DI 1072 | XORQ DI, SI 1073 | MOVQ R12, DI 1074 | RORQ $0x07, DI 1075 | XORQ R12, DI 1076 | MOVQ R12, R8 1077 | RORQ $0x29, R8 1078 | XORQ R8, DI 1079 | 1080 | // End round 2 1081 | 1082 | // Start round 3 1083 | // Round constant 1084 | XORQ $0x00000096, BX 1085 | 1086 | // Substitution 1087 | XORQ DI, CX 1088 | XORQ SI, DI 1089 | XORQ DX, BX 1090 | 1091 | // Keccak S-box 1092 | MOVQ DX, R9 1093 | NOTQ R9 1094 | MOVQ BX, R8 1095 | ANDQ R9, R8 1096 | XORQ CX, R8 1097 | MOVQ BX, R10 1098 | NOTQ R10 1099 | MOVQ SI, R9 1100 | ANDQ R10, R9 1101 | XORQ DX, R9 1102 | MOVQ SI, R11 1103 | NOTQ R11 1104 | MOVQ DI, R10 1105 | ANDQ R11, R10 1106 | XORQ BX, R10 1107 | MOVQ DI, BX 1108 | NOTQ BX 1109 | MOVQ CX, R11 1110 | ANDQ BX, R11 1111 | XORQ SI, R11 1112 | NOTQ CX 1113 | MOVQ DX, R12 1114 | ANDQ CX, R12 1115 | XORQ DI, R12 1116 | 1117 | // Substituton 1118 | XORQ R8, R9 1119 | XORQ R12, R8 1120 | XORQ R10, R11 1121 | NOTQ R10 1122 | 1123 | // Linear diffusion 1124 | MOVQ R8, CX 1125 | RORQ $0x13, CX 1126 | XORQ R8, CX 1127 | MOVQ R8, DX 1128 | RORQ $0x1c, DX 1129 | XORQ DX, CX 1130 | MOVQ R9, DX 1131 | RORQ $0x3d, DX 1132 | XORQ R9, DX 1133 | MOVQ R9, BX 1134 | RORQ $0x27, BX 1135 | XORQ BX, DX 1136 | MOVQ R10, BX 1137 | RORQ $0x01, BX 1138 | XORQ R10, BX 1139 | MOVQ R10, SI 1140 | RORQ $0x06, SI 1141 | XORQ SI, BX 1142 | MOVQ R11, SI 1143 | RORQ $0x0a, SI 1144 | XORQ R11, SI 1145 | MOVQ R11, DI 1146 | RORQ $0x11, DI 1147 | XORQ DI, SI 1148 | MOVQ R12, DI 1149 | RORQ $0x07, DI 1150 | XORQ R12, DI 1151 | MOVQ R12, R8 1152 | RORQ $0x29, R8 1153 | XORQ R8, DI 1154 | 1155 | // End round 3 1156 | 1157 | // Start round 4 1158 | // Round constant 1159 | XORQ $0x00000087, BX 1160 | 1161 | // Substitution 1162 | XORQ DI, CX 1163 | XORQ SI, DI 1164 | XORQ DX, BX 1165 | 1166 | // Keccak S-box 1167 | MOVQ DX, R9 1168 | NOTQ R9 1169 | MOVQ BX, R8 1170 | ANDQ R9, R8 1171 | XORQ CX, R8 1172 | MOVQ BX, R10 1173 | NOTQ R10 1174 | MOVQ SI, R9 1175 | ANDQ R10, R9 1176 | XORQ DX, R9 1177 | MOVQ SI, R11 1178 | NOTQ R11 1179 | MOVQ DI, R10 1180 | ANDQ R11, R10 1181 | XORQ BX, R10 1182 | MOVQ DI, BX 1183 | NOTQ BX 1184 | MOVQ CX, R11 1185 | ANDQ BX, R11 1186 | XORQ SI, R11 1187 | NOTQ CX 1188 | MOVQ DX, R12 1189 | ANDQ CX, R12 1190 | XORQ DI, R12 1191 | 1192 | // Substituton 1193 | XORQ R8, R9 1194 | XORQ R12, R8 1195 | XORQ R10, R11 1196 | NOTQ R10 1197 | 1198 | // Linear diffusion 1199 | MOVQ R8, CX 1200 | RORQ $0x13, CX 1201 | XORQ R8, CX 1202 | MOVQ R8, DX 1203 | RORQ $0x1c, DX 1204 | XORQ DX, CX 1205 | MOVQ R9, DX 1206 | RORQ $0x3d, DX 1207 | XORQ R9, DX 1208 | MOVQ R9, BX 1209 | RORQ $0x27, BX 1210 | XORQ BX, DX 1211 | MOVQ R10, BX 1212 | RORQ $0x01, BX 1213 | XORQ R10, BX 1214 | MOVQ R10, SI 1215 | RORQ $0x06, SI 1216 | XORQ SI, BX 1217 | MOVQ R11, SI 1218 | RORQ $0x0a, SI 1219 | XORQ R11, SI 1220 | MOVQ R11, DI 1221 | RORQ $0x11, DI 1222 | XORQ DI, SI 1223 | MOVQ R12, DI 1224 | RORQ $0x07, DI 1225 | XORQ R12, DI 1226 | MOVQ R12, R8 1227 | RORQ $0x29, R8 1228 | XORQ R8, DI 1229 | 1230 | // End round 4 1231 | 1232 | // Start round 5 1233 | // Round constant 1234 | XORQ $0x00000078, BX 1235 | 1236 | // Substitution 1237 | XORQ DI, CX 1238 | XORQ SI, DI 1239 | XORQ DX, BX 1240 | 1241 | // Keccak S-box 1242 | MOVQ DX, R9 1243 | NOTQ R9 1244 | MOVQ BX, R8 1245 | ANDQ R9, R8 1246 | XORQ CX, R8 1247 | MOVQ BX, R10 1248 | NOTQ R10 1249 | MOVQ SI, R9 1250 | ANDQ R10, R9 1251 | XORQ DX, R9 1252 | MOVQ SI, R11 1253 | NOTQ R11 1254 | MOVQ DI, R10 1255 | ANDQ R11, R10 1256 | XORQ BX, R10 1257 | MOVQ DI, BX 1258 | NOTQ BX 1259 | MOVQ CX, R11 1260 | ANDQ BX, R11 1261 | XORQ SI, R11 1262 | NOTQ CX 1263 | MOVQ DX, R12 1264 | ANDQ CX, R12 1265 | XORQ DI, R12 1266 | 1267 | // Substituton 1268 | XORQ R8, R9 1269 | XORQ R12, R8 1270 | XORQ R10, R11 1271 | NOTQ R10 1272 | 1273 | // Linear diffusion 1274 | MOVQ R8, CX 1275 | RORQ $0x13, CX 1276 | XORQ R8, CX 1277 | MOVQ R8, DX 1278 | RORQ $0x1c, DX 1279 | XORQ DX, CX 1280 | MOVQ R9, DX 1281 | RORQ $0x3d, DX 1282 | XORQ R9, DX 1283 | MOVQ R9, BX 1284 | RORQ $0x27, BX 1285 | XORQ BX, DX 1286 | MOVQ R10, BX 1287 | RORQ $0x01, BX 1288 | XORQ R10, BX 1289 | MOVQ R10, SI 1290 | RORQ $0x06, SI 1291 | XORQ SI, BX 1292 | MOVQ R11, SI 1293 | RORQ $0x0a, SI 1294 | XORQ R11, SI 1295 | MOVQ R11, DI 1296 | RORQ $0x11, DI 1297 | XORQ DI, SI 1298 | MOVQ R12, DI 1299 | RORQ $0x07, DI 1300 | XORQ R12, DI 1301 | MOVQ R12, R8 1302 | RORQ $0x29, R8 1303 | XORQ R8, DI 1304 | 1305 | // End round 5 1306 | 1307 | // Start round 6 1308 | // Round constant 1309 | XORQ $0x00000069, BX 1310 | 1311 | // Substitution 1312 | XORQ DI, CX 1313 | XORQ SI, DI 1314 | XORQ DX, BX 1315 | 1316 | // Keccak S-box 1317 | MOVQ DX, R9 1318 | NOTQ R9 1319 | MOVQ BX, R8 1320 | ANDQ R9, R8 1321 | XORQ CX, R8 1322 | MOVQ BX, R10 1323 | NOTQ R10 1324 | MOVQ SI, R9 1325 | ANDQ R10, R9 1326 | XORQ DX, R9 1327 | MOVQ SI, R11 1328 | NOTQ R11 1329 | MOVQ DI, R10 1330 | ANDQ R11, R10 1331 | XORQ BX, R10 1332 | MOVQ DI, BX 1333 | NOTQ BX 1334 | MOVQ CX, R11 1335 | ANDQ BX, R11 1336 | XORQ SI, R11 1337 | NOTQ CX 1338 | MOVQ DX, R12 1339 | ANDQ CX, R12 1340 | XORQ DI, R12 1341 | 1342 | // Substituton 1343 | XORQ R8, R9 1344 | XORQ R12, R8 1345 | XORQ R10, R11 1346 | NOTQ R10 1347 | 1348 | // Linear diffusion 1349 | MOVQ R8, CX 1350 | RORQ $0x13, CX 1351 | XORQ R8, CX 1352 | MOVQ R8, DX 1353 | RORQ $0x1c, DX 1354 | XORQ DX, CX 1355 | MOVQ R9, DX 1356 | RORQ $0x3d, DX 1357 | XORQ R9, DX 1358 | MOVQ R9, BX 1359 | RORQ $0x27, BX 1360 | XORQ BX, DX 1361 | MOVQ R10, BX 1362 | RORQ $0x01, BX 1363 | XORQ R10, BX 1364 | MOVQ R10, SI 1365 | RORQ $0x06, SI 1366 | XORQ SI, BX 1367 | MOVQ R11, SI 1368 | RORQ $0x0a, SI 1369 | XORQ R11, SI 1370 | MOVQ R11, DI 1371 | RORQ $0x11, DI 1372 | XORQ DI, SI 1373 | MOVQ R12, DI 1374 | RORQ $0x07, DI 1375 | XORQ R12, DI 1376 | MOVQ R12, R8 1377 | RORQ $0x29, R8 1378 | XORQ R8, DI 1379 | 1380 | // End round 6 1381 | 1382 | // Start round 7 1383 | // Round constant 1384 | XORQ $0x0000005a, BX 1385 | 1386 | // Substitution 1387 | XORQ DI, CX 1388 | XORQ SI, DI 1389 | XORQ DX, BX 1390 | 1391 | // Keccak S-box 1392 | MOVQ DX, R9 1393 | NOTQ R9 1394 | MOVQ BX, R8 1395 | ANDQ R9, R8 1396 | XORQ CX, R8 1397 | MOVQ BX, R10 1398 | NOTQ R10 1399 | MOVQ SI, R9 1400 | ANDQ R10, R9 1401 | XORQ DX, R9 1402 | MOVQ SI, R11 1403 | NOTQ R11 1404 | MOVQ DI, R10 1405 | ANDQ R11, R10 1406 | XORQ BX, R10 1407 | MOVQ DI, BX 1408 | NOTQ BX 1409 | MOVQ CX, R11 1410 | ANDQ BX, R11 1411 | XORQ SI, R11 1412 | NOTQ CX 1413 | MOVQ DX, R12 1414 | ANDQ CX, R12 1415 | XORQ DI, R12 1416 | 1417 | // Substituton 1418 | XORQ R8, R9 1419 | XORQ R12, R8 1420 | XORQ R10, R11 1421 | NOTQ R10 1422 | 1423 | // Linear diffusion 1424 | MOVQ R8, CX 1425 | RORQ $0x13, CX 1426 | XORQ R8, CX 1427 | MOVQ R8, DX 1428 | RORQ $0x1c, DX 1429 | XORQ DX, CX 1430 | MOVQ R9, DX 1431 | RORQ $0x3d, DX 1432 | XORQ R9, DX 1433 | MOVQ R9, BX 1434 | RORQ $0x27, BX 1435 | XORQ BX, DX 1436 | MOVQ R10, BX 1437 | RORQ $0x01, BX 1438 | XORQ R10, BX 1439 | MOVQ R10, SI 1440 | RORQ $0x06, SI 1441 | XORQ SI, BX 1442 | MOVQ R11, SI 1443 | RORQ $0x0a, SI 1444 | XORQ R11, SI 1445 | MOVQ R11, DI 1446 | RORQ $0x11, DI 1447 | XORQ DI, SI 1448 | MOVQ R12, DI 1449 | RORQ $0x07, DI 1450 | XORQ R12, DI 1451 | MOVQ R12, R8 1452 | RORQ $0x29, R8 1453 | XORQ R8, DI 1454 | 1455 | // End round 7 1456 | 1457 | // Start round 8 1458 | // Round constant 1459 | XORQ $0x0000004b, BX 1460 | 1461 | // Substitution 1462 | XORQ DI, CX 1463 | XORQ SI, DI 1464 | XORQ DX, BX 1465 | 1466 | // Keccak S-box 1467 | MOVQ DX, R9 1468 | NOTQ R9 1469 | MOVQ BX, R8 1470 | ANDQ R9, R8 1471 | XORQ CX, R8 1472 | MOVQ BX, R10 1473 | NOTQ R10 1474 | MOVQ SI, R9 1475 | ANDQ R10, R9 1476 | XORQ DX, R9 1477 | MOVQ SI, R11 1478 | NOTQ R11 1479 | MOVQ DI, R10 1480 | ANDQ R11, R10 1481 | XORQ BX, R10 1482 | MOVQ DI, BX 1483 | NOTQ BX 1484 | MOVQ CX, R11 1485 | ANDQ BX, R11 1486 | XORQ SI, R11 1487 | NOTQ CX 1488 | MOVQ DX, R12 1489 | ANDQ CX, R12 1490 | XORQ DI, R12 1491 | 1492 | // Substituton 1493 | XORQ R8, R9 1494 | XORQ R12, R8 1495 | XORQ R10, R11 1496 | NOTQ R10 1497 | 1498 | // Linear diffusion 1499 | MOVQ R8, CX 1500 | RORQ $0x13, CX 1501 | XORQ R8, CX 1502 | MOVQ R8, DX 1503 | RORQ $0x1c, DX 1504 | XORQ DX, CX 1505 | MOVQ R9, DX 1506 | RORQ $0x3d, DX 1507 | XORQ R9, DX 1508 | MOVQ R9, BX 1509 | RORQ $0x27, BX 1510 | XORQ BX, DX 1511 | MOVQ R10, BX 1512 | RORQ $0x01, BX 1513 | XORQ R10, BX 1514 | MOVQ R10, SI 1515 | RORQ $0x06, SI 1516 | XORQ SI, BX 1517 | MOVQ R11, SI 1518 | RORQ $0x0a, SI 1519 | XORQ R11, SI 1520 | MOVQ R11, DI 1521 | RORQ $0x11, DI 1522 | XORQ DI, SI 1523 | MOVQ R12, DI 1524 | RORQ $0x07, DI 1525 | XORQ R12, DI 1526 | MOVQ R12, R8 1527 | RORQ $0x29, R8 1528 | XORQ R8, DI 1529 | 1530 | // End round 8 1531 | 1532 | MOVQ CX, (AX) 1533 | MOVQ DX, 8(AX) 1534 | MOVQ BX, 16(AX) 1535 | MOVQ SI, 24(AX) 1536 | MOVQ DI, 32(AX) 1537 | RET 1538 | 1539 | // func p6(s *state) 1540 | TEXT ·p6(SB), NOSPLIT, $0-8 1541 | MOVQ s+0(FP), AX 1542 | MOVQ (AX), CX 1543 | MOVQ 8(AX), DX 1544 | MOVQ 16(AX), BX 1545 | MOVQ 24(AX), SI 1546 | MOVQ 32(AX), DI 1547 | 1548 | // Start round 1 1549 | // Round constant 1550 | XORQ $0x00000096, BX 1551 | 1552 | // Substitution 1553 | XORQ DI, CX 1554 | XORQ SI, DI 1555 | XORQ DX, BX 1556 | 1557 | // Keccak S-box 1558 | MOVQ DX, R9 1559 | NOTQ R9 1560 | MOVQ BX, R8 1561 | ANDQ R9, R8 1562 | XORQ CX, R8 1563 | MOVQ BX, R10 1564 | NOTQ R10 1565 | MOVQ SI, R9 1566 | ANDQ R10, R9 1567 | XORQ DX, R9 1568 | MOVQ SI, R11 1569 | NOTQ R11 1570 | MOVQ DI, R10 1571 | ANDQ R11, R10 1572 | XORQ BX, R10 1573 | MOVQ DI, BX 1574 | NOTQ BX 1575 | MOVQ CX, R11 1576 | ANDQ BX, R11 1577 | XORQ SI, R11 1578 | NOTQ CX 1579 | MOVQ DX, R12 1580 | ANDQ CX, R12 1581 | XORQ DI, R12 1582 | 1583 | // Substituton 1584 | XORQ R8, R9 1585 | XORQ R12, R8 1586 | XORQ R10, R11 1587 | NOTQ R10 1588 | 1589 | // Linear diffusion 1590 | MOVQ R8, CX 1591 | RORQ $0x13, CX 1592 | XORQ R8, CX 1593 | MOVQ R8, DX 1594 | RORQ $0x1c, DX 1595 | XORQ DX, CX 1596 | MOVQ R9, DX 1597 | RORQ $0x3d, DX 1598 | XORQ R9, DX 1599 | MOVQ R9, BX 1600 | RORQ $0x27, BX 1601 | XORQ BX, DX 1602 | MOVQ R10, BX 1603 | RORQ $0x01, BX 1604 | XORQ R10, BX 1605 | MOVQ R10, SI 1606 | RORQ $0x06, SI 1607 | XORQ SI, BX 1608 | MOVQ R11, SI 1609 | RORQ $0x0a, SI 1610 | XORQ R11, SI 1611 | MOVQ R11, DI 1612 | RORQ $0x11, DI 1613 | XORQ DI, SI 1614 | MOVQ R12, DI 1615 | RORQ $0x07, DI 1616 | XORQ R12, DI 1617 | MOVQ R12, R8 1618 | RORQ $0x29, R8 1619 | XORQ R8, DI 1620 | 1621 | // End round 1 1622 | 1623 | // Start round 2 1624 | // Round constant 1625 | XORQ $0x00000087, BX 1626 | 1627 | // Substitution 1628 | XORQ DI, CX 1629 | XORQ SI, DI 1630 | XORQ DX, BX 1631 | 1632 | // Keccak S-box 1633 | MOVQ DX, R9 1634 | NOTQ R9 1635 | MOVQ BX, R8 1636 | ANDQ R9, R8 1637 | XORQ CX, R8 1638 | MOVQ BX, R10 1639 | NOTQ R10 1640 | MOVQ SI, R9 1641 | ANDQ R10, R9 1642 | XORQ DX, R9 1643 | MOVQ SI, R11 1644 | NOTQ R11 1645 | MOVQ DI, R10 1646 | ANDQ R11, R10 1647 | XORQ BX, R10 1648 | MOVQ DI, BX 1649 | NOTQ BX 1650 | MOVQ CX, R11 1651 | ANDQ BX, R11 1652 | XORQ SI, R11 1653 | NOTQ CX 1654 | MOVQ DX, R12 1655 | ANDQ CX, R12 1656 | XORQ DI, R12 1657 | 1658 | // Substituton 1659 | XORQ R8, R9 1660 | XORQ R12, R8 1661 | XORQ R10, R11 1662 | NOTQ R10 1663 | 1664 | // Linear diffusion 1665 | MOVQ R8, CX 1666 | RORQ $0x13, CX 1667 | XORQ R8, CX 1668 | MOVQ R8, DX 1669 | RORQ $0x1c, DX 1670 | XORQ DX, CX 1671 | MOVQ R9, DX 1672 | RORQ $0x3d, DX 1673 | XORQ R9, DX 1674 | MOVQ R9, BX 1675 | RORQ $0x27, BX 1676 | XORQ BX, DX 1677 | MOVQ R10, BX 1678 | RORQ $0x01, BX 1679 | XORQ R10, BX 1680 | MOVQ R10, SI 1681 | RORQ $0x06, SI 1682 | XORQ SI, BX 1683 | MOVQ R11, SI 1684 | RORQ $0x0a, SI 1685 | XORQ R11, SI 1686 | MOVQ R11, DI 1687 | RORQ $0x11, DI 1688 | XORQ DI, SI 1689 | MOVQ R12, DI 1690 | RORQ $0x07, DI 1691 | XORQ R12, DI 1692 | MOVQ R12, R8 1693 | RORQ $0x29, R8 1694 | XORQ R8, DI 1695 | 1696 | // End round 2 1697 | 1698 | // Start round 3 1699 | // Round constant 1700 | XORQ $0x00000078, BX 1701 | 1702 | // Substitution 1703 | XORQ DI, CX 1704 | XORQ SI, DI 1705 | XORQ DX, BX 1706 | 1707 | // Keccak S-box 1708 | MOVQ DX, R9 1709 | NOTQ R9 1710 | MOVQ BX, R8 1711 | ANDQ R9, R8 1712 | XORQ CX, R8 1713 | MOVQ BX, R10 1714 | NOTQ R10 1715 | MOVQ SI, R9 1716 | ANDQ R10, R9 1717 | XORQ DX, R9 1718 | MOVQ SI, R11 1719 | NOTQ R11 1720 | MOVQ DI, R10 1721 | ANDQ R11, R10 1722 | XORQ BX, R10 1723 | MOVQ DI, BX 1724 | NOTQ BX 1725 | MOVQ CX, R11 1726 | ANDQ BX, R11 1727 | XORQ SI, R11 1728 | NOTQ CX 1729 | MOVQ DX, R12 1730 | ANDQ CX, R12 1731 | XORQ DI, R12 1732 | 1733 | // Substituton 1734 | XORQ R8, R9 1735 | XORQ R12, R8 1736 | XORQ R10, R11 1737 | NOTQ R10 1738 | 1739 | // Linear diffusion 1740 | MOVQ R8, CX 1741 | RORQ $0x13, CX 1742 | XORQ R8, CX 1743 | MOVQ R8, DX 1744 | RORQ $0x1c, DX 1745 | XORQ DX, CX 1746 | MOVQ R9, DX 1747 | RORQ $0x3d, DX 1748 | XORQ R9, DX 1749 | MOVQ R9, BX 1750 | RORQ $0x27, BX 1751 | XORQ BX, DX 1752 | MOVQ R10, BX 1753 | RORQ $0x01, BX 1754 | XORQ R10, BX 1755 | MOVQ R10, SI 1756 | RORQ $0x06, SI 1757 | XORQ SI, BX 1758 | MOVQ R11, SI 1759 | RORQ $0x0a, SI 1760 | XORQ R11, SI 1761 | MOVQ R11, DI 1762 | RORQ $0x11, DI 1763 | XORQ DI, SI 1764 | MOVQ R12, DI 1765 | RORQ $0x07, DI 1766 | XORQ R12, DI 1767 | MOVQ R12, R8 1768 | RORQ $0x29, R8 1769 | XORQ R8, DI 1770 | 1771 | // End round 3 1772 | 1773 | // Start round 4 1774 | // Round constant 1775 | XORQ $0x00000069, BX 1776 | 1777 | // Substitution 1778 | XORQ DI, CX 1779 | XORQ SI, DI 1780 | XORQ DX, BX 1781 | 1782 | // Keccak S-box 1783 | MOVQ DX, R9 1784 | NOTQ R9 1785 | MOVQ BX, R8 1786 | ANDQ R9, R8 1787 | XORQ CX, R8 1788 | MOVQ BX, R10 1789 | NOTQ R10 1790 | MOVQ SI, R9 1791 | ANDQ R10, R9 1792 | XORQ DX, R9 1793 | MOVQ SI, R11 1794 | NOTQ R11 1795 | MOVQ DI, R10 1796 | ANDQ R11, R10 1797 | XORQ BX, R10 1798 | MOVQ DI, BX 1799 | NOTQ BX 1800 | MOVQ CX, R11 1801 | ANDQ BX, R11 1802 | XORQ SI, R11 1803 | NOTQ CX 1804 | MOVQ DX, R12 1805 | ANDQ CX, R12 1806 | XORQ DI, R12 1807 | 1808 | // Substituton 1809 | XORQ R8, R9 1810 | XORQ R12, R8 1811 | XORQ R10, R11 1812 | NOTQ R10 1813 | 1814 | // Linear diffusion 1815 | MOVQ R8, CX 1816 | RORQ $0x13, CX 1817 | XORQ R8, CX 1818 | MOVQ R8, DX 1819 | RORQ $0x1c, DX 1820 | XORQ DX, CX 1821 | MOVQ R9, DX 1822 | RORQ $0x3d, DX 1823 | XORQ R9, DX 1824 | MOVQ R9, BX 1825 | RORQ $0x27, BX 1826 | XORQ BX, DX 1827 | MOVQ R10, BX 1828 | RORQ $0x01, BX 1829 | XORQ R10, BX 1830 | MOVQ R10, SI 1831 | RORQ $0x06, SI 1832 | XORQ SI, BX 1833 | MOVQ R11, SI 1834 | RORQ $0x0a, SI 1835 | XORQ R11, SI 1836 | MOVQ R11, DI 1837 | RORQ $0x11, DI 1838 | XORQ DI, SI 1839 | MOVQ R12, DI 1840 | RORQ $0x07, DI 1841 | XORQ R12, DI 1842 | MOVQ R12, R8 1843 | RORQ $0x29, R8 1844 | XORQ R8, DI 1845 | 1846 | // End round 4 1847 | 1848 | // Start round 5 1849 | // Round constant 1850 | XORQ $0x0000005a, BX 1851 | 1852 | // Substitution 1853 | XORQ DI, CX 1854 | XORQ SI, DI 1855 | XORQ DX, BX 1856 | 1857 | // Keccak S-box 1858 | MOVQ DX, R9 1859 | NOTQ R9 1860 | MOVQ BX, R8 1861 | ANDQ R9, R8 1862 | XORQ CX, R8 1863 | MOVQ BX, R10 1864 | NOTQ R10 1865 | MOVQ SI, R9 1866 | ANDQ R10, R9 1867 | XORQ DX, R9 1868 | MOVQ SI, R11 1869 | NOTQ R11 1870 | MOVQ DI, R10 1871 | ANDQ R11, R10 1872 | XORQ BX, R10 1873 | MOVQ DI, BX 1874 | NOTQ BX 1875 | MOVQ CX, R11 1876 | ANDQ BX, R11 1877 | XORQ SI, R11 1878 | NOTQ CX 1879 | MOVQ DX, R12 1880 | ANDQ CX, R12 1881 | XORQ DI, R12 1882 | 1883 | // Substituton 1884 | XORQ R8, R9 1885 | XORQ R12, R8 1886 | XORQ R10, R11 1887 | NOTQ R10 1888 | 1889 | // Linear diffusion 1890 | MOVQ R8, CX 1891 | RORQ $0x13, CX 1892 | XORQ R8, CX 1893 | MOVQ R8, DX 1894 | RORQ $0x1c, DX 1895 | XORQ DX, CX 1896 | MOVQ R9, DX 1897 | RORQ $0x3d, DX 1898 | XORQ R9, DX 1899 | MOVQ R9, BX 1900 | RORQ $0x27, BX 1901 | XORQ BX, DX 1902 | MOVQ R10, BX 1903 | RORQ $0x01, BX 1904 | XORQ R10, BX 1905 | MOVQ R10, SI 1906 | RORQ $0x06, SI 1907 | XORQ SI, BX 1908 | MOVQ R11, SI 1909 | RORQ $0x0a, SI 1910 | XORQ R11, SI 1911 | MOVQ R11, DI 1912 | RORQ $0x11, DI 1913 | XORQ DI, SI 1914 | MOVQ R12, DI 1915 | RORQ $0x07, DI 1916 | XORQ R12, DI 1917 | MOVQ R12, R8 1918 | RORQ $0x29, R8 1919 | XORQ R8, DI 1920 | 1921 | // End round 5 1922 | 1923 | // Start round 6 1924 | // Round constant 1925 | XORQ $0x0000004b, BX 1926 | 1927 | // Substitution 1928 | XORQ DI, CX 1929 | XORQ SI, DI 1930 | XORQ DX, BX 1931 | 1932 | // Keccak S-box 1933 | MOVQ DX, R9 1934 | NOTQ R9 1935 | MOVQ BX, R8 1936 | ANDQ R9, R8 1937 | XORQ CX, R8 1938 | MOVQ BX, R10 1939 | NOTQ R10 1940 | MOVQ SI, R9 1941 | ANDQ R10, R9 1942 | XORQ DX, R9 1943 | MOVQ SI, R11 1944 | NOTQ R11 1945 | MOVQ DI, R10 1946 | ANDQ R11, R10 1947 | XORQ BX, R10 1948 | MOVQ DI, BX 1949 | NOTQ BX 1950 | MOVQ CX, R11 1951 | ANDQ BX, R11 1952 | XORQ SI, R11 1953 | NOTQ CX 1954 | MOVQ DX, R12 1955 | ANDQ CX, R12 1956 | XORQ DI, R12 1957 | 1958 | // Substituton 1959 | XORQ R8, R9 1960 | XORQ R12, R8 1961 | XORQ R10, R11 1962 | NOTQ R10 1963 | 1964 | // Linear diffusion 1965 | MOVQ R8, CX 1966 | RORQ $0x13, CX 1967 | XORQ R8, CX 1968 | MOVQ R8, DX 1969 | RORQ $0x1c, DX 1970 | XORQ DX, CX 1971 | MOVQ R9, DX 1972 | RORQ $0x3d, DX 1973 | XORQ R9, DX 1974 | MOVQ R9, BX 1975 | RORQ $0x27, BX 1976 | XORQ BX, DX 1977 | MOVQ R10, BX 1978 | RORQ $0x01, BX 1979 | XORQ R10, BX 1980 | MOVQ R10, SI 1981 | RORQ $0x06, SI 1982 | XORQ SI, BX 1983 | MOVQ R11, SI 1984 | RORQ $0x0a, SI 1985 | XORQ R11, SI 1986 | MOVQ R11, DI 1987 | RORQ $0x11, DI 1988 | XORQ DI, SI 1989 | MOVQ R12, DI 1990 | RORQ $0x07, DI 1991 | XORQ R12, DI 1992 | MOVQ R12, R8 1993 | RORQ $0x29, R8 1994 | XORQ R8, DI 1995 | 1996 | // End round 6 1997 | 1998 | MOVQ CX, (AX) 1999 | MOVQ DX, 8(AX) 2000 | MOVQ BX, 16(AX) 2001 | MOVQ SI, 24(AX) 2002 | MOVQ DI, 32(AX) 2003 | RET 2004 | 2005 | // func round(s *state, C uint64) 2006 | TEXT ·round(SB), NOSPLIT, $0-16 2007 | MOVQ s+0(FP), AX 2008 | MOVQ (AX), CX 2009 | MOVQ 8(AX), DX 2010 | MOVQ 16(AX), BX 2011 | MOVQ 24(AX), SI 2012 | MOVQ 32(AX), DI 2013 | MOVQ C+8(FP), R8 2014 | 2015 | // Round constant 2016 | XORQ R8, BX 2017 | 2018 | // Substitution 2019 | XORQ DI, CX 2020 | XORQ SI, DI 2021 | XORQ DX, BX 2022 | 2023 | // Keccak S-box 2024 | MOVQ DX, R9 2025 | NOTQ R9 2026 | MOVQ BX, R8 2027 | ANDQ R9, R8 2028 | XORQ CX, R8 2029 | MOVQ BX, R10 2030 | NOTQ R10 2031 | MOVQ SI, R9 2032 | ANDQ R10, R9 2033 | XORQ DX, R9 2034 | MOVQ SI, R11 2035 | NOTQ R11 2036 | MOVQ DI, R10 2037 | ANDQ R11, R10 2038 | XORQ BX, R10 2039 | MOVQ DI, BX 2040 | NOTQ BX 2041 | MOVQ CX, R11 2042 | ANDQ BX, R11 2043 | XORQ SI, R11 2044 | NOTQ CX 2045 | MOVQ DX, R12 2046 | ANDQ CX, R12 2047 | XORQ DI, R12 2048 | 2049 | // Substituton 2050 | XORQ R8, R9 2051 | XORQ R12, R8 2052 | XORQ R10, R11 2053 | NOTQ R10 2054 | 2055 | // Linear diffusion 2056 | MOVQ R8, CX 2057 | RORQ $0x13, CX 2058 | XORQ R8, CX 2059 | MOVQ R8, DX 2060 | RORQ $0x1c, DX 2061 | XORQ DX, CX 2062 | MOVQ R9, DX 2063 | RORQ $0x3d, DX 2064 | XORQ R9, DX 2065 | MOVQ R9, BX 2066 | RORQ $0x27, BX 2067 | XORQ BX, DX 2068 | MOVQ R10, BX 2069 | RORQ $0x01, BX 2070 | XORQ R10, BX 2071 | MOVQ R10, SI 2072 | RORQ $0x06, SI 2073 | XORQ SI, BX 2074 | MOVQ R11, SI 2075 | RORQ $0x0a, SI 2076 | XORQ R11, SI 2077 | MOVQ R11, DI 2078 | RORQ $0x11, DI 2079 | XORQ DI, SI 2080 | MOVQ R12, DI 2081 | RORQ $0x07, DI 2082 | XORQ R12, DI 2083 | MOVQ R12, R8 2084 | RORQ $0x29, R8 2085 | XORQ R8, DI 2086 | MOVQ CX, (AX) 2087 | MOVQ DX, 8(AX) 2088 | MOVQ BX, 16(AX) 2089 | MOVQ SI, 24(AX) 2090 | MOVQ DI, 32(AX) 2091 | RET 2092 | 2093 | // func additionalData128a(s *state, ad []byte) 2094 | TEXT ·additionalData128a(SB), NOSPLIT, $0-32 2095 | JMP ·additionalData128aGeneric(SB) 2096 | RET 2097 | 2098 | // func encryptBlocks128a(s *state, dst []byte, src []byte) 2099 | TEXT ·encryptBlocks128a(SB), NOSPLIT, $0-56 2100 | JMP ·encryptBlocks128aGeneric(SB) 2101 | RET 2102 | 2103 | // func decryptBlocks128a(s *state, dst []byte, src []byte) 2104 | TEXT ·decryptBlocks128a(SB), NOSPLIT, $0-56 2105 | JMP ·decryptBlocks128aGeneric(SB) 2106 | RET 2107 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 4 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 5 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 6 | github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= 7 | github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= 8 | github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= 9 | github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= 10 | github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= 11 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 12 | github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 13 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 14 | github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 15 | github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= 16 | github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= 17 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= 18 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= 19 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 20 | github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= 21 | github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= 22 | github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= 23 | github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= 24 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 25 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 26 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 27 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= 28 | github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= 29 | github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= 30 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 31 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 32 | github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= 33 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 34 | github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= 35 | github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= 36 | github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 37 | github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 38 | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 39 | github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= 40 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 41 | github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= 42 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 43 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 44 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 45 | github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= 46 | github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= 47 | github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= 48 | github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= 49 | github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= 50 | github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= 51 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 52 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 53 | github.com/ericlagergren/saferand v0.0.0-20211228043234-529f04ad6e1a h1:3UO1DBvRL8/6uPtg75UP4XwAV+eFOQxvBxk0aOQue6Y= 54 | github.com/ericlagergren/saferand v0.0.0-20211228043234-529f04ad6e1a/go.mod h1:ETASDWf/FmEb6Ysrtd1QhjNedUU/ZQxBCRLh60bQ/UI= 55 | github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010 h1:fuGucgPk5dN6wzfnxl3D0D3rVLw4v2SbBT9jb4VnxzA= 56 | github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010/go.mod h1:JtBcj7sBuTTRupn7c2bFspMDIObMJsVK8TeUvpShPok= 57 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 58 | github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= 59 | github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= 60 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 61 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 62 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 63 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 64 | github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 65 | github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= 66 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 67 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 68 | github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= 69 | github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= 70 | github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 71 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 72 | github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= 73 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 74 | github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 75 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 76 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 77 | github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 78 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 79 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 80 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 81 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 82 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 83 | github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 84 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 85 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 86 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 87 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 88 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 89 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 90 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 91 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 92 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 93 | github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 94 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 95 | github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= 96 | github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= 97 | github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= 98 | github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= 99 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= 100 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= 101 | github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= 102 | github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= 103 | github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= 104 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 105 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 106 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= 107 | github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= 108 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= 109 | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= 110 | github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= 111 | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= 112 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 113 | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 114 | github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 115 | github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= 116 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 117 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 118 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= 119 | github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= 120 | github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= 121 | github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= 122 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 123 | github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= 124 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 125 | github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= 126 | github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= 127 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= 128 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 129 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 130 | github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 131 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 132 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 133 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= 134 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 135 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 136 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 137 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 138 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 139 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 140 | github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= 141 | github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= 142 | github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= 143 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 144 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 145 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 146 | github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= 147 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 148 | github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 149 | github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= 150 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 151 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= 152 | github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= 153 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= 154 | github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 155 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 156 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 157 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 158 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 159 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 160 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 161 | github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= 162 | github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= 163 | github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= 164 | github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= 165 | github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= 166 | github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= 167 | github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= 168 | github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= 169 | github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= 170 | github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= 171 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 172 | github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 173 | github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 174 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= 175 | github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= 176 | github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= 177 | github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= 178 | github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= 179 | github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= 180 | github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= 181 | github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= 182 | github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= 183 | github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= 184 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= 185 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 186 | github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= 187 | github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= 188 | github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= 189 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 190 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 191 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 192 | github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= 193 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 194 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= 195 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 196 | github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= 197 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= 198 | github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= 199 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 200 | github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 201 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 202 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 203 | github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 204 | github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 205 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 206 | github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= 207 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 208 | github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 209 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 210 | github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= 211 | github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= 212 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 213 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 214 | github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= 215 | github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM= 216 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 217 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= 218 | github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= 219 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 220 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 221 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 222 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 223 | github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 224 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 225 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 226 | github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= 227 | github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= 228 | github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= 229 | github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 230 | github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= 231 | github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= 232 | github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= 233 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 234 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 235 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 236 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 237 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 238 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 239 | github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= 240 | github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= 241 | github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= 242 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= 243 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 244 | github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 245 | go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= 246 | go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= 247 | go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= 248 | go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= 249 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 250 | go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= 251 | go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= 252 | go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= 253 | go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= 254 | go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= 255 | go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 256 | go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= 257 | go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= 258 | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= 259 | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= 260 | go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= 261 | go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= 262 | go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= 263 | go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= 264 | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= 265 | go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= 266 | go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= 267 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 268 | golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 269 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 270 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 271 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 272 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 273 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 274 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 275 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 276 | golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= 277 | golang.org/x/exp v0.0.0-20211221223016-e29036178569/go.mod h1:b9TAUYHmRtqA6klRHApnXMnj+OyLce4yF5cZCUbk2ps= 278 | golang.org/x/exp v0.0.0-20220428152302-39d4317da171 h1:TfdoLivD44QwvssI9Sv1xwa5DcL5XQr4au4sZ2F2NV4= 279 | golang.org/x/exp v0.0.0-20220428152302-39d4317da171/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= 280 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 281 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 282 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 283 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 284 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 285 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 286 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 287 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 288 | golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= 289 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 290 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 291 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 292 | golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 293 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 294 | golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= 295 | golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= 296 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 297 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 298 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 299 | golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 300 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 301 | golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 302 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 303 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 304 | golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 305 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 306 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 307 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 308 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 309 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 310 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 311 | golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 312 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 313 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 314 | golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 315 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 316 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 317 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 318 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 319 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 320 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 321 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 322 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 323 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 324 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 325 | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 326 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 327 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 328 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 329 | golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 330 | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 331 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 332 | golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 333 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 334 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 335 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 336 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 337 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 338 | golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 339 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 340 | golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 341 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 342 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 343 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 344 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 345 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 346 | golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 347 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 348 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 349 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 350 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 351 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 352 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 353 | golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 354 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 355 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 356 | golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 357 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 358 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 359 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 360 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 361 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 362 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 363 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 364 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 365 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 366 | golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 367 | golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 368 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 369 | golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 370 | golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 371 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 372 | golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= 373 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 374 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 375 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 376 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 377 | google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= 378 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 379 | google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 380 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 381 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 382 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 383 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 384 | google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= 385 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 386 | google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= 387 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 388 | google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= 389 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 390 | google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 391 | google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 392 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 393 | google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 394 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 395 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 396 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 397 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 398 | gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= 399 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 400 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 401 | gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= 402 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= 403 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 404 | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 405 | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= 406 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 407 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 408 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 409 | honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 410 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 411 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 412 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 413 | honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= 414 | sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= 415 | sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= 416 | --------------------------------------------------------------------------------