From: Mark Wooding Date: Mon, 16 Dec 2019 17:20:15 +0000 (+0000) Subject: Merge branch '2.4.x' into 2.5.x X-Git-Tag: 2.5.2~8 X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/commitdiff_plain/89717a56084f7cac56330c8527fbaff99b15709b?hp=3f078a9c1d674e911f8c4169930359d603ccd5fb Merge branch '2.4.x' into 2.5.x * 2.4.x: rand/rand.c: Mix the pool key in `rand_gate' and `rand_stretch'. rand/lcrand.c: Swap flags and max so generator not advertised as strong. pub/dh-kcdsa.c: Free the correct factor. math/limlee.c: Don't leak the factor vector on overall failure. math/limlee.c: Handle an abort from `pgen' correctly. math/pgen.c: Don't free the tester if it's not set up. math/ec-exp.h: Fix segfault when base point is at infinity. key/key-data.c (key_copydata): Fix catastrophic bug. key/key-data.c (key_split): Fix long-standing reference leak. key/key-misc.c (key_bytag): Don't give up because a by-id search fails. base/dispatch.c, etc.: Check that `rdrand' works. --- diff --git a/.gitignore b/.gitignore index 1d7acb58..9c2b37dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,61 +1,10 @@ Makefile.in -aclocal.m4 -configure -COPYING.LIB -autom4te.cache -config -precomp -progs/getdate.h -progs/getdate.y -symm/modes.am -symm/stubs.am +/aclocal.m4 +/configure +/COPYING.LIB +/autom4te.cache/ +/config/ +/precomp/ *.sage.py *.t *.to -/symm/safersk.h -/symm/salsa2012.h -/symm/salsa208.h -/symm/salsa20-ietf.h -/symm/salsa2012-ietf.h -/symm/salsa208-ietf.h -/symm/sha224.h -/symm/sha384.h -/symm/whirlpool256.h -/symm/xsalsa20.h -/symm/xsalsa2012.h -/symm/xsalsa208.h -/symm/stubs.gen-stamp -/symm/t/salsa20 -/symm/xchacha12.h -/symm/xchacha20.h -/symm/xchacha8.h -/symm/chacha12.h -/symm/chacha20.h -/symm/chacha8.h -/symm/chacha12-ietf.h -/symm/chacha20-ietf.h -/symm/chacha8-ietf.h -/symm/xchacha.h -/symm/kmac128.h -/symm/kmac256.h -/symm/safersk.c -/symm/sha224.c -/symm/sha3-224.c -/symm/sha3-224.h -/symm/sha3-256.c -/symm/sha3-256.h -/symm/sha3-384.c -/symm/sha3-384.h -/symm/sha3-512.c -/symm/sha3-512.h -/symm/sha384.c -/symm/sha512-224.c -/symm/sha512-224.h -/symm/sha512-256.c -/symm/sha512-256.h -/symm/shake128.h -/symm/shake256.h -/symm/t/sha3 -/symm/whirlpool256.c -/symm/shake128-xof.h -/symm/shake256-xof.h diff --git a/base/Makefile.am b/base/Makefile.am index c9560ca2..145f9c35 100644 --- a/base/Makefile.am +++ b/base/Makefile.am @@ -29,6 +29,8 @@ include $(top_srcdir)/vars.am noinst_LTLIBRARIES = libbase.la libbase_la_SOURCES = +TEST_LIBS = libbase.la + ###-------------------------------------------------------------------------- ### Component files. @@ -55,7 +57,29 @@ libbase_la_SOURCES += lmem.c ## Clearing secrets from memory. pkginclude_HEADERS += paranoia.h +## Reservoir handling. +pkginclude_HEADERS += rsvr.h +libbase_la_SOURCES += rsvr.c +TESTS += rsvr.t$(EXEEXT) +EXTRA_DIST += t/rsvr + ## Base definitions for assembler source. EXTRA_DIST += asm-common.h +if ASM_DEBUG +libbase_la_SOURCES += regdump.c regdump.h +if CPUFAM_X86 +libbase_la_SOURCES += regdump-x86ish.S +endif +if CPUFAM_AMD64 +libbase_la_SOURCES += regdump-x86ish.S +endif +if CPUFAM_ARMEL +libbase_la_SOURCES += regdump-arm.S +endif +if CPUFAM_ARM64 +libbase_la_SOURCES += regdump-arm64.S +endif +endif + ###----- That's all, folks -------------------------------------------------- diff --git a/base/asm-common.h b/base/asm-common.h index 8e51ea39..44c223da 100644 --- a/base/asm-common.h +++ b/base/asm-common.h @@ -24,6 +24,9 @@ /// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, /// MA 02111-1307, USA. +#ifndef CATACOMB_ASM_COMMON_H +#define CATACOMB_ASM_COMMON_H + ///-------------------------------------------------------------------------- /// General definitions. @@ -217,11 +220,11 @@ name: # define INTADDR__1(addr, got) addr #endif -// Permutations for SIMD instructions. SHUF(D, C, B, A) is an immediate, -// suitable for use in `pshufd' or `shufpd', which copies element D -// (0 <= D < 4) of the source to element 3 of the destination, element C to -// element 2, element B to element 1, and element A to element 0. -#define SHUF(d, c, b, a) (64*(d) + 16*(c) + 4*(b) + (a)) +// Permutations for SIMD instructions. SHUF(A, B, C, D) is an immediate, +// suitable for use in `pshufd' or `shufpd', which copies element A +// (0 <= A < 4) of the source to element 0 of the destination, element B to +// element 1, element C to element 2, and element D to element 3. +#define SHUF(a, b, c, d) ((a) + 4*(b) + 16*(c) + 64*(d)) // Map register names to their individual pieces. @@ -255,10 +258,10 @@ name: # define _DECOR_abcd_q(reg) r##reg##x #endif -#define _DECOR_xp_b(reg) reg##l #define _DECOR_xp_w(reg) reg #define _DECOR_xp_d(reg) e##reg #if CPUFAM_AMD64 +# define _DECOR_xp_b(reg) reg##l # define _DECOR_xp_q(reg) r##reg #endif @@ -276,22 +279,33 @@ name: # define _DECOR_rn_r(reg) reg #endif +#define _DECOR_mem_b(addr) byte ptr addr +#define _DECOR_mem_w(addr) word ptr addr +#define _DECOR_mem_d(addr) dword ptr addr +#if CPUFAM_AMD64 +# define _DECOR_mem_q(addr) qword ptr addr +#endif + +#define _DECOR_imm_b(imm) byte imm +#define _DECOR_imm_w(imm) word imm +#define _DECOR_imm_d(imm) dword imm +#if CPUFAM_AMD64 +# define _DECOR_imm_q(imm) qword imm +#endif + #if CPUFAM_X86 # define _DECOR_abcd_r(reg) e##reg##x # define _DECOR_xp_r(reg) e##reg # define _DECOR_ip_r(reg) e##reg +# define _DECOR_mem_r(addr) dword ptr addr +# define _DECOR_imm_r(imm) dword imm #endif #if CPUFAM_AMD64 # define _DECOR_abcd_r(reg) r##reg##x # define _DECOR_xp_r(reg) r##reg # define _DECOR_ip_r(reg) r##reg -#endif - -#define _DECOR_mem_b(addr) byte ptr addr -#define _DECOR_mem_w(addr) word ptr addr -#define _DECOR_mem_d(addr) dword ptr addr -#if CPUFAM_AMD64 -# define _DECOR_mem_q(addr) qword ptr addr +# define _DECOR_mem_r(addr) qword ptr addr +# define _DECOR_imm_r(imm) qword imm #endif // R_r(decor) applies decoration decor to register r, which is an internal @@ -321,6 +335,9 @@ name: // address addr (which should supply its own square-brackets). #define MEM(decor, addr) _DECOR(mem, decor, addr) +// Refer to an immediate datum of the type implied by decor. +#define IMM(decor, imm) _DECOR(mem, decor, imm) + // Applies decoration decor to assembler-level register name reg. #define _REGFORM(reg, decor) _GLUE(_REGFORM_, reg)(decor) @@ -436,7 +453,7 @@ name: #define WHOLE(reg) _REGFORM(reg, r) // Stack management and unwinding. -.macro setfp fp, offset = 0 +.macro setfp fp=R_bp(r), offset=0 .if \offset == 0 mov \fp, R_sp(r) #if __ELF__ @@ -459,7 +476,7 @@ name: .macro dropfp; _dropfp \fp, \offset; .endm .endm -.macro _dropfp fp, offset = 0 +.macro _dropfp fp, offset=0 .if \offset == 0 mov R_sp(r), \fp #if __ELF__ @@ -532,117 +549,6 @@ name: #endif -#if CPUFAM_X86 - -.macro _reg.0 - // Stash GP registers and establish temporary stack frame. - pushfd - push eax - push ecx - push edx - push ebp - mov ebp, esp - and esp, ~15 - sub esp, 512 - fxsave [esp] -.endm - -.macro _reg.1 -.endm - -.macro _reg.2 -.endm - -.macro _reg.3 fmt - // Print FMT and the other established arguments. - lea eax, .L$_reg$msg.\@ - push eax - call printf - jmp .L$_reg$cont.\@ -.L$_reg$msg.\@: - .ascii ";; \fmt\n\0" -.L$_reg$cont.\@: - mov eax, ebp - and eax, ~15 - sub eax, 512 - fxrstor [eax] - mov esp, ebp - pop ebp - pop edx - pop ecx - pop eax - popfd -.endm - -.macro msg msg - _reg.0 - _reg.1 - _reg.2 - _reg.3 "\msg" -.endm - -.macro reg r, msg - _reg.0 - .ifeqs "\r", "esp" - lea eax, [ebp + 20] - push eax - .else - .ifeqs "\r", "ebp" - push [ebp] - .else - push \r - .endif - .endif - _reg.1 - _reg.2 - _reg.3 "\msg: \r = %08x" -.endm - -.macro xmmreg r, msg - _reg.0 - _reg.1 - _reg.2 - movdqu xmm0, \r - pshufd xmm0, xmm0, 0x1b - sub esp, 16 - movdqa [esp], xmm0 - _reg.3 "\msg: \r = %08x %08x %08x %08x" -.endm - -.macro mmreg r, msg - _reg.0 - _reg.1 - _reg.2 - pshufw \r, \r, 0x4e - sub esp, 8 - movq [esp], \r - _reg.3 "\msg: \r = %08x %08x" -.endm - -.macro freg i, msg - _reg.0 - _reg.1 - _reg.2 - finit - fldt [esp + 32 + 16*\i] - sub esp, 12 - fstpt [esp] - _reg.3 "\msg: st(\i) = %.20Lg" -.endm - -.macro fxreg i, msg - _reg.0 - _reg.1 - _reg.2 - finit - fldt [esp + 32 + 16*\i] - sub esp, 12 - fstpt [esp] - _reg.3 "\msg: st(\i) = %La" -.endm - -#endif - ///-------------------------------------------------------------------------- /// ARM-specific hacking. @@ -706,12 +612,12 @@ name: #if WANT_PIC ldr\cond \reg, .L$_leaextq$\@ .L$_leaextq_pc$\@: - .if .L$_pcoff == 8 + .if .L$_pcoff == 8 ldr\cond \reg, [pc, \reg] - .else + .else add\cond \reg, pc ldr\cond \reg, [\reg] - .endif + .endif _LIT .balign 4 .L$_leaextq$\@: @@ -722,6 +628,29 @@ name: #endif .endm +.macro vzero vz=q15 + // Set VZ (default q15) to zero. + vmov.u32 \vz, #0 +.endm + +.macro vshl128 vd, vn, nbit, vz=q15 + // Set VD to VN shifted left by NBIT. Assume VZ (default q15) is + // all-bits-zero. NBIT must be a multiple of 8. + .if \nbit&3 != 0 + .error "shift quantity must be whole number of bytes" + .endif + vext.8 \vd, \vz, \vn, #16 - (\nbit >> 3) +.endm + +.macro vshr128 vd, vn, nbit, vz=q15 + // Set VD to VN shifted right by NBIT. Assume VZ (default q15) is + // all-bits-zero. NBIT must be a multiple of 8. + .if \nbit&3 != 0 + .error "shift quantity must be whole number of bytes" + .endif + vext.8 \vd, \vn, \vz, #\nbit >> 3 +.endm + // Apply decoration decor to register name reg. #define _REGFORM(reg, decor) _GLUE(_REGFORM_, reg)(decor) @@ -972,7 +901,7 @@ name: #define QQ(qlo, qhi) D0(qlo)-D1(qhi) // Stack management and unwinding. -.macro setfp fp, offset = 0 +.macro setfp fp=r11, offset=0 .if \offset == 0 mov \fp, sp .setfp \fp, sp @@ -984,7 +913,7 @@ name: .L$_frameptr_p = -1 .endm -.macro _dropfp fp, offset = 0 +.macro _dropfp fp, offset=0 .if \offset == 0 mov sp, \fp .else @@ -1005,12 +934,12 @@ name: .endm .macro pushreg rr:vararg - stmfd sp!, {\rr} + push {\rr} .save {\rr} .endm .macro popreg rr:vararg - ldmfd sp!, {\rr} + pop {\rr} .endm .macro pushvfp rr:vararg @@ -1056,8 +985,31 @@ name: #endif .endm +.macro vzero vz=v31 + // Set VZ (default v31) to zero. + dup \vz\().4s, wzr +.endm + +.macro vshl128 vd, vn, nbit, vz=v31 + // Set VD to VN shifted left by NBIT. Assume VZ (default v31) is + // all-bits-zero. NBIT must be a multiple of 8. + .if \nbit&3 != 0 + .error "shift quantity must be whole number of bytes" + .endif + ext \vd\().16b, \vz\().16b, \vn\().16b, #16 - (\nbit >> 3) +.endm + +.macro vshr128 vd, vn, nbit, vz=v31 + // Set VD to VN shifted right by NBIT. Assume VZ (default v31) is + // all-bits-zero. NBIT must be a multiple of 8. + .if \nbit&3 != 0 + .error "shift quantity must be whole number of bytes" + .endif + ext \vd\().16b, \vn\().16b, \vz\().16b, #\nbit >> 3 +.endm + // Stack management and unwinding. -.macro setfp fp, offset = 0 +.macro setfp fp=x29, offset=0 // If you're just going through the motions with a fixed-size stack frame, // then you want to say `add x29, sp, #OFFSET' directly, which will avoid // pointlessly restoring sp later. @@ -1073,7 +1025,7 @@ name: .L$_frameptr_p = -1 .endm -.macro _dropfp fp, offset = 0 +.macro _dropfp fp, offset=0 .if \offset == 0 mov sp, \fp .cfi_def_cfa_register sp @@ -1096,8 +1048,8 @@ name: .cfi_adjust_cfa_offset -\n .endm -.macro pushreg x, y= - .ifeqs "\y", "" +.macro pushreg x, y=nil + .ifeqs "\y", "nil" str \x, [sp, #-16]! .cfi_adjust_cfa_offset +16 .cfi_rel_offset \x, 0 @@ -1109,8 +1061,8 @@ name: .endif .endm -.macro popreg x, y= - .ifeqs "\y", "" +.macro popreg x, y=nil + .ifeqs "\y", "nil" ldr \x, [sp], #16 .cfi_restore \x .cfi_adjust_cfa_offset -16 @@ -1122,9 +1074,9 @@ name: .endif .endm -.macro savereg x, y, z= - .ifeqs "\z", "" - str \x, [sp, #\y] +.macro savereg x, y, z=nil + .ifeqs "\z", "nil" + str \x, [sp, \y] .cfi_rel_offset \x, \y .else stp \x, \y, [sp, #\z] @@ -1133,9 +1085,9 @@ name: .endif .endm -.macro rstrreg x, y, z= - .ifeqs "\z", "" - ldr \x, [sp, #\y] +.macro rstrreg x, y, z=nil + .ifeqs "\z", "nil" + ldr \x, [sp, \y] .cfi_restore \x .else ldp \x, \y, [sp, #\z] @@ -1164,7 +1116,11 @@ name: #endif #ifndef F -# define F(name) name +# ifdef SYM_USCORE +# define F(name) _##name +# else +# define F(name) name +# endif #endif #ifndef TYPE_FUNC @@ -1181,3 +1137,5 @@ name: #endif ///----- That's all, folks -------------------------------------------------- + +#endif diff --git a/base/dispatch.c b/base/dispatch.c index 42c64ee5..abd019f6 100644 --- a/base/dispatch.c +++ b/base/dispatch.c @@ -46,7 +46,10 @@ # define EFLAGS_ID (1u << 21) # define CPUID1D_SSE2 (1u << 26) # define CPUID1D_FXSR (1u << 24) +# define CPUID1C_PCLMUL (1u << 1) +# define CPUID1C_SSSE3 (1u << 9) # define CPUID1C_AESNI (1u << 25) +# define CPUID1C_AVX (1u << 28) # define CPUID1C_RDRAND (1u << 30) struct cpuid { unsigned a, b, c, d; }; @@ -334,13 +337,15 @@ static unsigned hwcaps = 0; _(ARM_NEON, "arm:neon") \ _(ARM_V4, "arm:v4") \ _(ARM_D32, "arm:d32") \ - _(ARM_AES, "arm:aes") + _(ARM_AES, "arm:aes") \ + _(ARM_PMULL, "arm:pmull") #endif #if CPUFAM_ARM64 # define WANTAUX(_) \ WANT_AT_HWCAP(_) # define CAPMAP(_) \ - _(ARM_AES, "arm:aes") + _(ARM_AES, "arm:aes") \ + _(ARM_PMULL, "arm:pmull") #endif /* Build the bitmask for `hwcaps' from the `CAPMAP' list. */ @@ -454,9 +459,13 @@ static void probe_hwcaps(void) # ifdef HWCAP2_AES if (probed.hwcap2 & HWCAP2_AES) hw |= HF_ARM_AES; # endif +# ifdef HWCAP2_PMULL + if (probed.hwcap2 & HWCAP2_PMULL) hw |= HF_ARM_PMULL; +# endif #endif #if CPUFAM_ARM64 if (probed.hwcap & HWCAP_AES) hw |= HF_ARM_AES; + if (probed.hwcap & HWCAP_PMULL) hw |= HF_ARM_PMULL; #endif /* Store the bitmask of features we probed for everyone to see. */ @@ -598,6 +607,15 @@ int cpu_feature_p(int feat) xmm_registers_available_p()); CASE_CPUFEAT(X86_RDRAND, "x86:rdrand", cpuid_features_p(0, CPUID1C_RDRAND) && rdrand_works_p()); + CASE_CPUFEAT(X86_AVX, "x86:avx", + cpuid_features_p(0, CPUID1C_AVX) && + xmm_registers_available_p()); + CASE_CPUFEAT(X86_SSSE3, "x86:ssse3", + cpuid_features_p(0, CPUID1C_SSSE3) && + xmm_registers_available_p()); + CASE_CPUFEAT(X86_PCLMUL, "x86:pclmul", + cpuid_features_p(0, CPUID1C_PCLMUL) && + xmm_registers_available_p()); #endif #ifdef CAPMAP # define FEATP__CASE(feat, tok) \ diff --git a/base/dispatch.h b/base/dispatch.h index f778068c..7c083821 100644 --- a/base/dispatch.h +++ b/base/dispatch.h @@ -181,7 +181,11 @@ enum { CPUFEAT_ARM_V4, /* VFPv4 and/or SIMD v2 */ CPUFEAT_ARM_D32, /* 32 double registers, not 16 */ CPUFEAT_X86_RDRAND, /* Built-in entropy source */ - CPUFEAT_ARM_AES /* AES instructions */ + CPUFEAT_ARM_AES, /* AES instructions */ + CPUFEAT_X86_AVX, /* AVX 1 (i.e., 256-bit YMM regs) */ + CPUFEAT_X86_SSSE3, /* Supplementary SSE 3 */ + CPUFEAT_X86_PCLMUL, /* Carry-less multiplication */ + CPUFEAT_ARM_PMULL /* Polynomial multiplication */ }; extern int cpu_feature_p(int /*feat*/); diff --git a/base/keysz.c b/base/keysz.c index 8e5e2caf..13d850a4 100644 --- a/base/keysz.c +++ b/base/keysz.c @@ -81,4 +81,43 @@ size_t keysz(size_t sz, const octet *ksz) return (0); } +/* --- @keysz_pad@ --- * + * + * Arguments: @size_t sz@ = a proposed key size + * @const octet *ksz@ = pointer to key size table + * + * Returns: A key size, at least as large as @sz@, or zero if no such + * size is available. + */ + +size_t keysz_pad(size_t sz, const octet *ksz) +{ + unsigned op = ksz[0]&KSZ_OPMASK; + unsigned wd = (ksz[0]&KSZ_16BIT) ? 2 : 1; + unsigned t, u, v; + + ksz++; +#define ARG(i) (wd == 1 ? ksz[i] : LOAD16(ksz + 2*i)) + switch (op) { + case KSZ_ANY: return (sz); + case KSZ_RANGE: + t = ARG(1); u = ARG(2); v = ARG(3); + if (v) { sz += v - 1; sz -= sz%v; } + if (u && sz > u) return (0); + if (sz < t) return (t); + return (sz); + case KSZ_SET: + u = 0; + for (;;) { + t = ARG(0); ksz += wd; if (!t) break; + if (sz <= t && (!u || u > t)) u = t; + } + return (u); + } +#undef ARG + + assert(((void)"bad key size table", 0)); + return (0); +} + /*----- That's all, folks -------------------------------------------------*/ diff --git a/base/keysz.h b/base/keysz.h index b83203b9..4ad772a0 100644 --- a/base/keysz.h +++ b/base/keysz.h @@ -88,6 +88,17 @@ extern size_t keysz(size_t /*sz*/, const octet */*ksz*/); #define KSZ_ASSERT(pre, sz) \ assert(((void)"Bad key size for " #pre, KSZ_CHECK(pre, sz))) +/* --- @keysz_pad@ --- * + * + * Arguments: @size_t sz@ = a proposed key size + * @const octet *ksz@ = pointer to key size table + * + * Returns: A key size, at least as large as @sz@, or zero if no such + * size is available. + */ + +extern size_t keysz_pad(size_t /*sz*/, const octet */*ksz*/); + /*----- Key size conversions ----------------------------------------------*/ /* --- @keysz_fromdl@, @_fromschnorr@, @_fromif@, @_fromec@ --- * diff --git a/base/regdump-arm.S b/base/regdump-arm.S new file mode 100644 index 00000000..963a60ee --- /dev/null +++ b/base/regdump-arm.S @@ -0,0 +1,184 @@ +/// -*- mode: asm; asm-comment-char: ?/ -*- +/// +/// Register dump and debugging for 32-bit ARM +/// +/// (c) 2019 Straylight/Edgeware +/// + +///----- Licensing notice --------------------------------------------------- +/// +/// This file is part of Catacomb. +/// +/// Catacomb is free software: you can redistribute it and/or modify it +/// under the terms of the GNU Library General Public License as published +/// by the Free Software Foundation; either version 2 of the License, or +/// (at your option) any later version. +/// +/// Catacomb is distributed in the hope that it will be useful, but +/// WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +/// Library General Public License for more details. +/// +/// You should have received a copy of the GNU Library General Public +/// License along with Catacomb. If not, write to the Free Software +/// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +/// USA. + +///-------------------------------------------------------------------------- +/// Preliminaries. + +#include "config.h" +#include "asm-common.h" +#include "regdump.h" + + .arch armv7-a + .fpu neon + + .text + +///-------------------------------------------------------------------------- +/// Main code. + +FUNC(regdump_gpsave) + endprologue + // On entry, r13 should point to `REGDUMP_GPSIZE' bytes of + // word-aligned storage to be the general-purpose save area, with r12 + // and r14 already saved. On exit, the initial registers are saved + // in this space, and modified: r4 points to the general-purpose save + // area, r6 holds the focus address (possibly already saved), r0 + // contains the number of bytes required in the extended save area, + // and other general-purpose registers are clobbered or used to + // communicate with `regdump_xtsave' below. Doing anything other + // than lowering the stack pointer and calling `regdump_xtsave' is + // not recommended. + + // Save the easy registers. + stmia r13, {r0-r11} + mov r4, r13 + + // Determine the previous stack pointer and save it. + add r0, r4, #REGDUMP_GPSIZE + str r0, [r4, #13*4] + + // Capture the status flags and return address. If the return + // address has its low bit set, then the caller was in Thumb state: + // clear the bit from the reconstructed PC, and set the corresponding + // CPSR bit. + mrs r0, cpsr + tst r14, #1 + bic r1, r14, #1 + orrne r0, r0, #0x00000020 + str r0, [r13, #4*REGIX_CPSR] + str r1, [r13, #15*4] + + // Load the focus address and save it as r6. + ldr r6, [r4, #4*REGIX_ADDR] + + // Determine the extended save area size. + ldgot + mov r0, #8 + 8 + leaext r12, regdump__flags + ldr r12, [r12] + tst r12, #REGF_VFP + addne r0, r0, #REGDUMP_FPSIZE_D16 + tstne r12, #REGF_D32 + addne r0, r0, #REGDUMP_FPSIZE_D32 - REGDUMP_FPSIZE_D16 + + // Done. + bx r14 + +ENDFUNC + +FUNC(regdump_gprstr) + endprologue + // On entry, r4 points to a general-purpose save area, established by + // `regdump_gpsave'. On exit, the general-purpose registers (other + // than r13 and r14) are restored to their original values. + + // Restore the processor flags. + ldr r0, [r4, #4*REGIX_CPSR] + msr cpsr_fs, r0 + + // Load the easy registers. + ldmia r4, {r0-r12} + + // Done. + bx r14 + +ENDFUNC + +FUNC(regdump_xtsave) + endprologue + // On entry, r13 points to an extended save area, of size determined + // by `regdump_gpsave' above. On exit, the save area is filled in + // and a handy map placed at its base. + + // Set up the map/extended save area pointer. + add r5, r13, #7 + bic r5, r5, #7 + + // Start by filling in the easy part of the map. + str r4, [r5, #regmap_gp] + + // Fetch the flags explaining what to do. + ldgot + leaext r12, regdump__flags + ldr r12, [r12] + + // Figure out whether there are VFP/NEON registers. + tst r12, #REGF_VFP + moveq r3, #0 + addne r3, r5, #regmap_size + str r3, [r5, #regmap_fp] + beq 9f + + // Get the FP status register. + vmrs r0, fpscr + str r0, [r3], #8 + + // At least the first 16. + vstmia r3!, {d0-d15} + + // Maybe the other 16 too. + tst r12, #REGF_D32 + vstmiane r3!, {d16-d31} + + // Done. +9: bx r14 + +ENDFUNC + +FUNC(regdump_xtrstr) + endprologue + // On entry, r5 points to a register-save map. On exit, the extended + // registers are restored from the save area, r4 (pointing to the + // general-purpose save area) is preserved, and the other general + // registers are clobbered. + + // Fetch the flags explaining what to do. + ldgot + leaext r12, regdump__flags + ldr r12, [r12] + + // Figure out if there are VFP/NEON registers. + tst r12, #REGF_VFP + beq 9f + ldr r3, [r5, #regmap_fp] + + // Load the FP status register. + ldr r0, [r3], #8 + vmsr fpscr, r0 + + // Load the first 16 registers. + vldmia r3!, {d0-d15} + + // And maybe the other 16. + tst r12, #REGF_D32 + vldmiane r3!, {d16-d31} + + // Done. +9: bx r14 + +ENDFUNC + +///----- That's all, folks -------------------------------------------------- diff --git a/base/regdump-arm64.S b/base/regdump-arm64.S new file mode 100644 index 00000000..81c9f8e7 --- /dev/null +++ b/base/regdump-arm64.S @@ -0,0 +1,204 @@ +/// -*- mode: asm; asm-comment-char: ?/ -*- +/// +/// Register dump and debugging for 64-bit ARM +/// +/// (c) 2019 Straylight/Edgeware +/// + +///----- Licensing notice --------------------------------------------------- +/// +/// This file is part of Catacomb. +/// +/// Catacomb is free software: you can redistribute it and/or modify it +/// under the terms of the GNU Library General Public License as published +/// by the Free Software Foundation; either version 2 of the License, or +/// (at your option) any later version. +/// +/// Catacomb is distributed in the hope that it will be useful, but +/// WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +/// Library General Public License for more details. +/// +/// You should have received a copy of the GNU Library General Public +/// License along with Catacomb. If not, write to the Free Software +/// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +/// USA. + +///-------------------------------------------------------------------------- +/// Preliminaries. + +#include "config.h" +#include "asm-common.h" +#include "regdump.h" + + .arch armv8-a + + .text + +///-------------------------------------------------------------------------- +/// Main code. + +FUNC(regdump_gpsave) + endprologue + // On entry, sp should point to `REGDUMP_GPSIZE' bytes of + // doubleword-aligned storage to be the general-purpose save area, + // with x16, x17, and x30 already saved. On exit, the initial + // registers are saved in this space, and modified: x20 points to the + // general-purpose save area, x22 holds the focus address (possibly + // already saved), x0 contains the number of bytes required in the + // extended save area, and other general-purpose registers are + // clobbered or used to communicate with `regdump_xtsave' below. + // Doing anything other than lowering the stack pointer and calling + // `regdump_xtsave' is not recommended. + + // Save the easy registers. + stp x0, x1, [sp, #0] + stp x2, x3, [sp, #16] + stp x4, x5, [sp, #32] + stp x6, x7, [sp, #48] + stp x8, x9, [sp, #64] + stp x10, x11, [sp, #80] + stp x12, x13, [sp, #96] + stp x14, x15, [sp, #112] + stp x18, x19, [sp, #144] + stp x20, x21, [sp, #160] + stp x22, x23, [sp, #176] + stp x24, x25, [sp, #192] + stp x26, x27, [sp, #208] + stp x28, x29, [sp, #224] + + mov x20, sp + + // Determine the previous stack pointer and save it. + add x0, x20, #REGDUMP_GPSIZE + str x0, [x20, #31*8] + + // Capture the status flags. + mrs x0, nzcv + str x0, [x20, #8*REGIX_NZCV] + + // Set the return address as our PC. + str x30, [x20, #8*REGIX_PC] + + // Load the focus address and save it as x22. + ldr x22, [x20, #8*REGIX_ADDR] + + // Determine the extended save area size. + mov x0, #REGDUMP_FPSIZE + + // Done. + ret + +ENDFUNC + +FUNC(regdump_gprstr) + endprologue + // On entry, x20 points to a general-purpose save area, established + // by `regdump_gpsave'. On exit, the general-purpose registers + // (other than x30 and sp) are restored to their original values. + + // Restore the processor flags. + ldr w0, [x20, #8*REGIX_NZCV] + msr nzcv, x0 + + // Load the easy registers. + ldp x0, x1, [sp, #0] + ldp x2, x3, [sp, #16] + ldp x4, x5, [sp, #32] + ldp x6, x7, [sp, #48] + ldp x8, x9, [sp, #64] + ldp x10, x11, [sp, #80] + ldp x12, x13, [sp, #96] + ldp x14, x15, [sp, #112] + ldp x16, x17, [sp, #128] + ldp x18, x19, [sp, #144] + ldp x20, x21, [sp, #160] + ldp x22, x23, [sp, #176] + ldp x24, x25, [sp, #192] + ldp x26, x27, [sp, #208] + ldp x28, x29, [sp, #224] + + // Done. + ret + +ENDFUNC + +FUNC(regdump_xtsave) + endprologue + // On entry, sp points to an extended save area, of size determined + // by `regdump_gpsave' above. On exit, the save area is filled in + // and a handy map placed at its base. + + // Set up the map/extended save area pointer. + mov x21, sp + + // Start by filling in the easy part of the map. + add x0, x21, #regmap_size + stp x20, x0, [x21] + + // Get the FP status register. + mrs x1, fpsr + mrs x2, fpcr + stp w1, w2, [x0], #8 + + // Store the SIMD registers. + stp q0, q1, [x0, #0] + stp q2, q3, [x0, #32] + stp q4, q5, [x0, #64] + stp q6, q7, [x0, #96] + stp q8, q9, [x0, #128] + stp q10, q11, [x0, #160] + stp q12, q13, [x0, #192] + stp q14, q15, [x0, #224] + stp q16, q17, [x0, #256] + stp q18, q19, [x0, #288] + stp q20, q21, [x0, #320] + stp q22, q23, [x0, #352] + stp q24, q25, [x0, #384] + stp q26, q27, [x0, #416] + stp q28, q29, [x0, #448] + stp q30, q31, [x0, #480] + + // Done. + ret + +ENDFUNC + +FUNC(regdump_xtrstr) + endprologue + // On entry, x21 points to a register-save map. On exit, the + // extended registers are restored from the save area, x20 (pointing + // to the general-purpose save area) is preserved, and the other + // general registers are clobbered. + + ldr x0, [x21, #regmap_fp] + + // Load the FP status and control registers. + ldp w1, w2, [x0], #8 + msr fpsr, x1 + msr fpcr, x2 + + // Load the SIMD registers. + ldp q0, q1, [x0, #0] + ldp q2, q3, [x0, #32] + ldp q4, q5, [x0, #64] + ldp q6, q7, [x0, #96] + ldp q8, q9, [x0, #128] + ldp q10, q11, [x0, #160] + ldp q12, q13, [x0, #192] + ldp q14, q15, [x0, #224] + ldp q16, q17, [x0, #256] + ldp q18, q19, [x0, #288] + ldp q20, q21, [x0, #320] + ldp q22, q23, [x0, #352] + ldp q24, q25, [x0, #384] + ldp q26, q27, [x0, #416] + ldp q28, q29, [x0, #448] + ldp q30, q31, [x0, #480] + + // Done. + ret + +ENDFUNC + +///----- That's all, folks -------------------------------------------------- diff --git a/base/regdump-x86ish.S b/base/regdump-x86ish.S new file mode 100644 index 00000000..e4dd8e80 --- /dev/null +++ b/base/regdump-x86ish.S @@ -0,0 +1,277 @@ +/// -*- mode: asm; asm-comment-char: ?/ -*- +/// +/// Register dump and debugging for x86 +/// +/// (c) 2019 Straylight/Edgeware +/// + +///----- Licensing notice --------------------------------------------------- +/// +/// This file is part of Catacomb. +/// +/// Catacomb is free software: you can redistribute it and/or modify it +/// under the terms of the GNU Library General Public License as published +/// by the Free Software Foundation; either version 2 of the License, or +/// (at your option) any later version. +/// +/// Catacomb is distributed in the hope that it will be useful, but +/// WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +/// Library General Public License for more details. +/// +/// You should have received a copy of the GNU Library General Public +/// License along with Catacomb. If not, write to the Free Software +/// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +/// USA. + +///-------------------------------------------------------------------------- +/// Preliminaries. + +#include "config.h" +#include "asm-common.h" +#include "regdump.h" + + .text + .arch pentium4 + .arch .xsave + +///-------------------------------------------------------------------------- +/// Main code. + +FUNC(regdump_gpsave) + endprologue + // On entry, r/esp should point to a return address and + // `REGDUMP_GPSIZE' bytes of word-aligned storage to be the + // general-purpose save area, with flags saved in the bottom word, + // r/eax saved in the fourth, and (on 32-bit x86) ebx in the fifth. + // On exit, the initial registers are saved in this space, and + // modified: r/ebp points to the general-purpose save area, ecx + // contains the number of bytes required in the extended save area, + // ebx is preserved on 32-bit x86, and other general-purpose + // registers are clobbered or used to communicate with + // `regdump_xtsave' below. Doing anything other than lowering the + // stack pointer and calling `regdump_xtsave' is not recommended. + + // Other code will insist that df is clear. + cld + + // Save r/ebp and establish it pointing to the save area. + mov [R_sp(r) + WORDSZ + REGIX_BP*WORDSZ], R_bp(r) + lea R_bp(r), [R_sp(r) + WORDSZ] + + // Save the other easy general-purpose registers. +#if !CPUFAM_X86 + mov [R_bp(r) + REGIX_BX*WORDSZ], R_b(r) +#endif + mov [R_bp(r) + REGIX_CX*WORDSZ], R_c(r) + mov [R_bp(r) + REGIX_DX*WORDSZ], R_d(r) + mov [R_bp(r) + REGIX_SI*WORDSZ], R_si(r) + mov [R_bp(r) + REGIX_DI*WORDSZ], R_di(r) +#if CPUFAM_AMD64 + mov [R_bp(r) + REGIX_R8*WORDSZ], R_r8(r) + mov [R_bp(r) + REGIX_R9*WORDSZ], R_r9(r) + mov [R_bp(r) + REGIX_R10*WORDSZ], R_r10(r) + mov [R_bp(r) + REGIX_R11*WORDSZ], R_r11(r) + mov [R_bp(r) + REGIX_R12*WORDSZ], R_r12(r) + mov [R_bp(r) + REGIX_R13*WORDSZ], R_r13(r) + mov [R_bp(r) + REGIX_R14*WORDSZ], R_r14(r) + mov [R_bp(r) + REGIX_R15*WORDSZ], R_r15(r) +#endif + + // Determine the previous stack pointer and save it. +#if CPUFAM_AMD64 && ABI_SYSV + lea R_a(r), [R_bp(r) + 128 + REGDUMP_GPSIZE] +#else + lea R_a(r), [R_bp(r) + REGDUMP_GPSIZE] +#endif + mov [R_bp(r) + REGIX_SP*WORDSZ], R_a(r) + + // Collect the return address and save it as r/eip. + mov R_a(r), [R_sp(r)] + mov [R_bp(r) + REGIX_IP*WORDSZ], R_a(r) + + // Save the segment registers. + lea R_a(r), [R_bp(r) + REGIX_GPLIM*WORDSZ] + mov [R_a(r) + 2*REGIX_CS], cs + mov [R_a(r) + 2*REGIX_DS], ds + mov [R_a(r) + 2*REGIX_SS], ss + mov [R_a(r) + 2*REGIX_ES], es + mov [R_a(r) + 2*REGIX_FS], fs + mov [R_a(r) + 2*REGIX_GS], gs + + // Determine the extended save area size. Preserve ebx on 32-bit x86 + // here, because the caller needs it for PLT-indirect calls. +#if CPUFAM_X86 + push ebx +#endif + mov eax, 0x01 + cpuid + test ecx, 1 << 26 + je 1f + + mov eax, 0x0d + mov ecx, 0x00 + cpuid + add ecx, regmap_size + 64 // map + align + jmp 8f + +1: mov ecx, 512 + regmap_size + 16 // fxsave + map + align + + // Done. +8: +#if CPUFAM_X86 + pop ebx +#endif + ret + +ENDFUNC + +FUNC(regdump_gprstr) + endprologue + // On entry, r/ebp points to a general-purpose save area, established + // by `regdump_gpsave'. On exit, the general-purpose registers + // (other than the stack pointer) are restored to their original + // values. + + // We assume nobody actually fiddled with the segment registers. So + // just the actual integer registers to do. + mov R_a(r), [R_bp(r) + REGIX_AX*WORDSZ] + mov R_b(r), [R_bp(r) + REGIX_BX*WORDSZ] + mov R_c(r), [R_bp(r) + REGIX_CX*WORDSZ] + mov R_d(r), [R_bp(r) + REGIX_DX*WORDSZ] + mov R_si(r), [R_bp(r) + REGIX_SI*WORDSZ] + mov R_di(r), [R_bp(r) + REGIX_DI*WORDSZ] +#if CPUFAM_AMD64 + mov R_r8(r), [R_bp(r) + REGIX_R8*WORDSZ] + mov R_r9(r), [R_bp(r) + REGIX_R9*WORDSZ] + mov R_r10(r), [R_bp(r) + REGIX_R10*WORDSZ] + mov R_r11(r), [R_bp(r) + REGIX_R11*WORDSZ] + mov R_r12(r), [R_bp(r) + REGIX_R12*WORDSZ] + mov R_r13(r), [R_bp(r) + REGIX_R13*WORDSZ] + mov R_r14(r), [R_bp(r) + REGIX_R14*WORDSZ] + mov R_r15(r), [R_bp(r) + REGIX_R15*WORDSZ] +#endif + mov R_bp(r), [R_bp(r) + REGIX_BP*WORDSZ] + + // Done. + ret + +ENDFUNC + +#ifdef CPUFAM_AMD64 +# define fxsave fxsave64 +# define fxrstor fxrstor64 +# define xsave xsave64 +# define xrstor xrstor64 +#endif + +FUNC(regdump_xtsave) + endprologue + // On entry, r/esp points to a return address and extended save area, + // of size determined by `regdump_gpsave' above. On exit, the save + // area is filled in and a handy map placed at its base, the x87 + // floating-point state is reset, r/ebp is left pointing to the + // register map, ebx is preserved on 32-bit x86, and the other + // general registers are clobbered. + + // Start by filling in the easy parts of the map. + mov [R_sp(r) + WORDSZ + regmap_gp], R_bp(r) + lea R_bp(r), [R_sp(r) + WORDSZ] + + xor eax, eax // clears rax too on amd64 + mov [R_bp(r) + regmap_avx], R_a(r) + + // Find out whether we use `xsave'. (Preserve ebx.) +#if CPUFAM_X86 + push ebx +#endif + mov eax, 0x01 + cpuid + test ecx, 1 << 26 + je 5f + + // We have the `xsave' machinery. Select the base address. + lea R_si(r), [R_sp(r) + WORDSZ + regmap_size + 63] + and R_si(r), ~63 + mov [R_bp(r) + regmap_fx], R_si(r) + + // Clear out the header area. + xor eax, eax + lea R_di(r), [R_si(r) + 512] + mov ecx, 16 + rep stosd + + // Save the registers. + mov eax, 0x00000007 + xor edx, edx + xsave [R_si(r)] + + // Establish the AVX pointer, if available. + test dword ptr [R_si(r) + 512], 4 // = xstate_bv + je 8f + + mov eax, 13 + mov ecx, 2 + cpuid + add R_b(r), R_si(r) + mov [R_bp(r) + regmap_avx], R_b(r) + + jmp 8f + + // We have only `fxsave'. Set the base address. +5: lea R_si(r), [R_sp(r) + WORDSZ + regmap_size + 15] + and R_si(r), ~15 + mov [R_bp(r) + regmap_fx], R_si(r) + + // Save the registers. + fxsave [R_si(r)] + + // Clear the x87 state; otherwise it can cause trouble later. +8: fninit + + // Done. +#if CPUFAM_X86 + pop ebx +#endif + ret + +ENDFUNC + +FUNC(regdump_xtrstr) + endprologue + // On entry, r/ebp points to a register-save map. On exit, the + // extended registers are restored from the save area; r/ebp is left + // pointing to the general-purpose save area, ebx is preserved on + // 32-bit x86, and the other general registers are clobbered. + + // Find the extended register dump. + mov R_si(r), [R_bp(r) + regmap_fx] + + // Probe to find out whether we have `xsave'. +#if CPUFAM_X86 + push ebx +#endif + mov eax, 0x01 + cpuid + test ecx, 1 << 26 + je 1f + + // We have the `xsave' machinery. + mov eax, 0x00000007 + xor edx, edx + xrstor [R_si(r)] + jmp 8f + + // We must fake it up. +1: fxrstor [R_si(r)] + + // Done. +8: mov R_bp(r), [R_bp(r) + regmap_gp] +#if CPUFAM_X86 + pop ebx +#endif + ret + +ENDFUNC + +///----- That's all, folks -------------------------------------------------- diff --git a/base/regdump.c b/base/regdump.c new file mode 100644 index 00000000..d4f5fdec --- /dev/null +++ b/base/regdump.c @@ -0,0 +1,945 @@ +/* -*-c-*- + * + * Register dumping and other diagnostic tools for assembler code + * + * (c) 2016 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include + +#include "dispatch.h" +#include "regdump.h" + +/*----- Low-level printing ------------------------------------------------*/ + +/* Currently these are good for all of our targets. */ +#define STEP_8 1 +#define TY_HEX_8 uint8 +#define P_HEX_8 "0x%02x" +#define TY_UNSGN_8 uint8 +#define P_UNSGN_8 "%3u" +#define PV_CHR_8 " `%c'" +#define PV_HEX_8 " %02x" +#define PV_UNSGN_8 "%4u" + +#define STEP_16 2 +#define TY_HEX_16 uint16 +#define P_HEX_16 "0x%04x" +#define TY_UNSGN_16 uint16 +#define P_UNSGN_16 "%5u" +#define TY_SGN_16 int16 +#define P_SGN_16 "%6d" +#define PV_HEX_16 " 0x%04x" +#define PV_UNSGN_16 "%9u" +#define PV_SGN_16 "%9d" + +#define STEP_32 4 +#define TY_HEX_32 uint32 +#define P_HEX_32 "0x%08x" +#define TY_UNSGN_32 uint32 +#define P_UNSGN_32 "%10u" +#define TY_SGN_32 int32 +#define P_SGN_32 "%11d" +#define TY_FLT_32 float +#define P_FLT_32 "%15.9g" +#define PV_HEX_32 " 0x%08x" +#define PV_UNSGN_32 "%19u" +#define PV_SGN_32 "%19d" +#define PV_FLT_32 "%19.9g" + +#if ULONG_MAX >> 31 > 0xffffffff +# define PL64 "l" +#else +# define PL64 "ll" +#endif +#define STEP_64 8 +#define TY_HEX_64 uint64 +#define P_HEX_64 "0x%016"PL64"x" +#define TY_UNSGN_64 uint64 +#define P_UNSGN_64 "%20"PL64"u" +#define TY_SGN_64 int64 +#define P_SGN_64 "%20"PL64"d" +#define TY_FLT_64 double +#define P_FLT_64 "%24.17g" +#define PV_HEX_64 " 0x%016"PL64"x" +#define PV_UNSGN_64 "%39"PL64"u" +#define PV_SGN_64 "%39"PL64"d" +#define PV_FLT_64 "%39.17g" + +#if CPUFAM_X86 +# define STEP_80 12 +#endif +#if CPUFAM_AMD64 +# define STEP_80 16 +#endif +#define TY_FLT_80 long double +#define P_FLT_80 "%29.21Lg" +#define PV_FLT_80 P_FLT_80 + +#if CPUFAM_X86 || CPUFAM_AMD64 +# define ARCH_FORMATS(_) \ + _(80, FLT) +#endif +#ifndef ARCH_FORMATS +# define ARCH_FORMATS(_) +#endif + +#define FORMATS(_) \ + ARCH_FORMATS(_) \ + _(64, HEX) _(64, FLT) _(64, UNSGN) _(64, SGN) \ + _(32, HEX) _(32, FLT) _(32, UNSGN) _(32, SGN) \ + _(16, HEX) _(16, UNSGN) _(16, SGN) \ + _(8, HEX) _(8, CHR) _(8, UNSGN) + +struct fmtinfo { + const unsigned char *p; + unsigned wd, f; +#define FMTF_VECTOR 1u +}; + +#define FMTFUNC_STD(w, fmt) \ + static void dump_##fmt##_##w(struct fmtinfo *fmt) \ + { \ + TY_##fmt##_##w x = *(const TY_##fmt##_##w *)fmt->p; \ + \ + if (fmt->f&FMTF_VECTOR) printf(PV_##fmt##_##w, x); \ + else printf(P_##fmt##_##w, x); \ + fmt->p += STEP_##w; fmt->wd += 8*STEP_##w; \ + } + +#define FMTFUNC_HEX(w) FMTFUNC_STD(w, HEX) +#define FMTFUNC_UNSGN(w) FMTFUNC_STD(w, UNSGN) +#define FMTFUNC_SGN(w) FMTFUNC_STD(w, SGN) +#define FMTFUNC_FLT(w) FMTFUNC_STD(w, FLT) +#define FMTFUNC_CHR(w) + +static void dump_CHR_8(struct fmtinfo *fmt) +{ + unsigned char x = *(const unsigned char *)fmt->p; + + if (x < 32 || x > 126) printf("\\x%02x", x); + else printf(" `%c'", x); + fmt->p += 1; fmt->wd += 8; +} + +#define FMTFUNC(w, fmt) FMTFUNC_##fmt(w) +FORMATS(FMTFUNC) +#undef FMTFUNC + +static const struct fmttab { + uint32 mask; + void (*fmt)(struct fmtinfo *); +} fmttab[] = { +#define FMTTAB(wd, fmt) { REGF_##fmt | REGF_##wd, dump_##fmt##_##wd }, + FORMATS(FMTTAB) +#undef FMTTAB + { 0, 0 } +}; + +/*----- Common subroutines ------------------------------------------------*/ + +/* --- @regwd@ --- * + * + * Arguments: @uint32 f@ = format control word; see @REGF_...@ + * + * Returns: The actual width of the operand, in bits. + * + * Use: If the operand is a vector (the @REGF_WDMASK@ field is + * nonzero) then return the width it denotes; otherwise, return + * the largest width implied by the @REGF_TYMASK@ field. + */ + +static unsigned regwd(uint32 f) +{ + unsigned wd = 1 << ((f®F_WDMASK) >> REGF_WDSHIFT); + + if (wd > 1) return (wd); + else if (f®F_80) return (80); + else if (f®F_64) return (64); + else if (f®F_32) return (32); + else if (f®F_16) return (16); + else if (f®F_8) return (8); + else { assert(0); return (1); } +} + +/* --- @regname@ --- * + * + * Arguments: @char *buf = pointer to output buffer@ + * @uint32 f@ = format control word; see @REGF_...@ + * + * Returns: Pointer to name string. + * + * Use: Return a pointer to the name of the register implied by @f@, + * or null if there is no register. Systematic register names + * can be built in the provided buffer. + */ + +static const char *regname(char *buf, uint32 f) +{ + unsigned wd = regwd(f); + unsigned src = f®F_SRCMASK; + unsigned ix = (f®F_IXMASK) >> REGF_IXSHIFT; + char *p = buf; + + switch (src) { + + case REGSRC_ABS: + return (0); + +#if CPUFAM_X86 || CPUFAM_AMD64 + case REGSRC_GP: + if (ix == REGIX_FLAGS) { + if (wd == 64) *p++ = 'r'; + else if (wd == 32) *p++ = 'e'; + else if (wd != 16) assert(0); + p += sprintf(p, "flags"); +#if CPUFAM_AMD64 + } else if (REGIX_R8 <= ix && ix <= REGIX_R15) { + p += sprintf(p, "r%u", ix - REGIX_R8 + 8); + switch (wd) { + case 64: break; + case 32: *p++ = 'd'; break; + case 16: *p++ = 'w'; break; + case 8: *p++ = 'l'; break; + default: assert(0); + } +# endif + } else { + if (wd == 64) *p++ = 'r'; + else if (wd == 32) *p++ = 'e'; + switch (ix) { + case REGIX_IP: *p++ = 'i'; *p++ = 'p'; goto longreg; + case REGIX_AX: *p++ = 'a'; goto shortreg; + case REGIX_BX: *p++ = 'b'; goto shortreg; + case REGIX_CX: *p++ = 'c'; goto shortreg; + case REGIX_DX: *p++ = 'd'; goto shortreg; + case REGIX_SI: *p++ = 's'; *p++ = 'i'; goto longreg; + case REGIX_DI: *p++ = 'd'; *p++ = 'i'; goto longreg; + case REGIX_BP: *p++ = 'b'; *p++ = 'p'; goto longreg; + case REGIX_SP: *p++ = 's'; *p++ = 'p'; goto longreg; + default: assert(0); + } + if (0) { + shortreg: + switch (wd) { + case 64: + case 32: + case 16: *p++ = 'x'; break; + case 8: *p++ = 'l'; break; + default: assert(0); + } + } else { + longreg: + switch (wd) { + case 64: + case 32: + case 16: break; + case 8: *p++ = 'l'; break; + default: assert(0); + } + } + } + *p++ = 0; + return (buf); + + case REGSRC_SEG: + assert(wd == 16); + switch (ix) { + case REGIX_CS: sprintf(buf, "cs"); break; + case REGIX_DS: sprintf(buf, "ds"); break; + case REGIX_SS: sprintf(buf, "ss"); break; + case REGIX_ES: sprintf(buf, "es"); break; + case REGIX_FS: sprintf(buf, "fs"); break; + case REGIX_GS: sprintf(buf, "gs"); break; + default: assert(0); + } + return (buf); + + case REGSRC_STMMX: + if (ix == REGIX_FPFLAGS) return (0); + if (f®F_80) sprintf(buf, "st(%u)", ix); + else sprintf(buf, "mm%u", ix); + return (buf); + + case REGSRC_SIMD: + if (ix == REGIX_FPFLAGS) return (0); + switch (wd) { + case 32: case 64: case 128: sprintf(buf, "xmm%u", ix); break; + case 256: sprintf(buf, "ymm%u", ix); break; + default: assert(0); + } + return (buf); +#endif + +#if CPUFAM_ARMEL + case REGSRC_GP: + if (ix == REGIX_CPSR) sprintf(buf, "cpsr"); + else if (ix == 15) sprintf(buf, "pc"); + else sprintf(buf, "r%u", ix); + return (buf); + case REGSRC_FP: + if (ix == REGIX_FPSCR) sprintf(buf, "fpscr"); + else { + switch (wd) { + case 32: *p++ = 's'; break; + case 64: *p++ = 'd'; break; + case 128: *p++ = 'q'; break; + default: assert(0); + } + p += sprintf(p, "%u", ix); + *p++ = 0; + } + return (buf); +#endif + +#if CPUFAM_ARM64 + case REGSRC_GP: + if (ix == REGIX_PC) sprintf(buf, "pc"); + else if (ix == REGIX_NZCV) sprintf(buf, "nzcv"); + else if (ix == 31 && wd == 64) sprintf(buf, "sp"); + else { + switch (wd) { + case 32: *p++ = 'w'; break; + case 64: *p++ = 'x'; break; + default: assert(0); + } + p += sprintf(p, "%u", ix); + *p++ = 0; + } + return (buf); + case REGSRC_FP: + if (ix == REGIX_FPFLAGS) sprintf(buf, "fpflags"); + else { + if (f®F_WDMASK) + *p++ = 'v'; + else switch (wd) { + case 8: *p++ = 'b'; break; + case 16: *p++ = 'h'; break; + case 32: *p++ = 's'; break; + case 64: *p++ = 'd'; break; + default: assert(0); + } + p += sprintf(p, "%u", ix); + *p++ = 0; + } + return (buf); +#endif + + default: + assert(0); + return ("???"); + } +} + +/*----- x86 and AMD64 -----------------------------------------------------*/ + +#if CPUFAM_X86 || CPUFAM_AMD64 + +#if CPUFAM_X86 +# define P_HEX_GP "0x%08x" +# define GP(gp) (gp).u32 +#endif +#if CPUFAM_AMD64 +# define P_HEX_GP "0x%016"PL64"x" +# define GP(gp) (gp).u64 +#endif + +void regdump_init(void) { ; } + +static void dump_flags(const char *lbl, const char *reg, gpreg f) +{ + printf(";; "); + if (lbl) printf("%s: ", lbl); + if (reg) printf("%s = ", reg); + printf(""P_HEX_GP"\n", GP(f)); + printf(";;\t\tstatus: %ccf %cpf %caf %czf %csf %cdf %cof\n", + (GP(f) >> 0)&1u ? '+' : '-', + (GP(f) >> 2)&1u ? '+' : '-', + (GP(f) >> 4)&1u ? '+' : '-', + (GP(f) >> 6)&1u ? '+' : '-', + (GP(f) >> 7)&1u ? '+' : '-', + (GP(f) >> 10)&1u ? '+' : '-', + (GP(f) >> 11)&1u ? '+' : '-'); + printf(";;\t\tsystem: %ctf %cif iopl=%d %cnt " + "%crf %cvm %cac %cvif %cvip %cid\n", + (GP(f) >> 8)&1u ? '+' : '-', + (GP(f) >> 9)&1u ? '+' : '-', + (int)((GP(f) >> 12)&1u), + (GP(f) >> 14)&1u ? '+' : '-', + (GP(f) >> 16)&1u ? '+' : '-', + (GP(f) >> 17)&1u ? '+' : '-', + (GP(f) >> 18)&1u ? '+' : '-', + (GP(f) >> 19)&1u ? '+' : '-', + (GP(f) >> 20)&1u ? '+' : '-', + (GP(f) >> 21)&1u ? '+' : '-'); +} + +static const char + *pcmap[] = { "sgl", "???", "dbl", "ext" }, + *rcmap[] = { "nr", "-∞", "+∞", "0" }; + +static void dump_fpflags(const char *lbl, const struct fxsave *fx) +{ + unsigned top = (fx->fsw >> 11)&7u; + unsigned tag = fx->ftw; + int skip = lbl ? strlen(lbl) + 2 : 0; + + printf(";; "); + if (lbl) printf("%s: ", lbl); + + printf(" fcw = 0x%04x: " + "%cim %cdm %czm %com %cum %cpm pc=%s rc=%s %cx\n", + fx->fcw, + (fx->fcw >> 0)&1u ? '+' : '-', + (fx->fcw >> 1)&1u ? '+' : '-', + (fx->fcw >> 2)&1u ? '+' : '-', + (fx->fcw >> 3)&1u ? '+' : '-', + (fx->fcw >> 4)&1u ? '+' : '-', + (fx->fcw >> 5)&1u ? '+' : '-', + pcmap[(fx->fcw >> 8)&3u], + rcmap[(fx->fcw >> 10)&3u], + (fx->fcw >> 12)&1u ? '+' : '-'); + printf(";; %*s fsw = 0x%04x: " + "%cie %cde %cze %coe %cue %cpe %csf %ces %cc0 %cc1 %cc2 %cc3 " + "top=%d %cb\n", + skip, "", + fx->fsw, + (fx->fsw >> 0)&1u ? '+' : '-', + (fx->fsw >> 1)&1u ? '+' : '-', + (fx->fsw >> 2)&1u ? '+' : '-', + (fx->fsw >> 3)&1u ? '+' : '-', + (fx->fsw >> 4)&1u ? '+' : '-', + (fx->fsw >> 5)&1u ? '+' : '-', + (fx->fsw >> 6)&1u ? '+' : '-', + (fx->fsw >> 7)&1u ? '+' : '-', + (fx->fsw >> 8)&1u ? '+' : '-', + (fx->fsw >> 9)&1u ? '+' : '-', + (fx->fsw >> 10)&1u ? '+' : '-', + (fx->fsw >> 14)&1u ? '+' : '-', + top, + (fx->fsw >> 15)&1u ? '+' : '-'); + printf(";; %*s ftw = 0x%02x\n", skip, "", tag); +} + +static void dump_mxflags(const char *lbl, const struct fxsave *fx) +{ + printf(";; "); + if (lbl) printf("%s: ", lbl); + + printf(" mxcsr = 0x%08x\n" + ";;\t\tmask = %cim %cdm %czm %com %cum %cpm\n" + ";;\t\t exc = %cie %cde %cze %coe %cue %cpe\n" + ";;\t\tmisc = %cdaz %cftz rc=%s\n", + fx->mxcsr, + (fx->mxcsr >> 7)&1u ? '+' : '-', + (fx->mxcsr >> 8)&1u ? '+' : '-', + (fx->mxcsr >> 9)&1u ? '+' : '-', + (fx->mxcsr >> 10)&1u ? '+' : '-', + (fx->mxcsr >> 11)&1u ? '+' : '-', + (fx->mxcsr >> 12)&1u ? '+' : '-', + (fx->mxcsr >> 0)&1u ? '+' : '-', + (fx->mxcsr >> 1)&1u ? '+' : '-', + (fx->mxcsr >> 2)&1u ? '+' : '-', + (fx->mxcsr >> 3)&1u ? '+' : '-', + (fx->mxcsr >> 4)&1u ? '+' : '-', + (fx->mxcsr >> 5)&1u ? '+' : '-', + (fx->mxcsr >> 6)&1u ? '+' : '-', + (fx->mxcsr >> 15)&1u ? '+' : '-', + rcmap[(fx->mxcsr >> 13)&3u]); +} + +#if CPUFAM_X86 +# define REGF_GPWD REGF_32 +#endif +#if CPUFAM_AMD64 +# define REGF_GPWD REGF_64 +#endif + +void regdump_gp(const struct regmap *map) +{ + unsigned i; + + printf(";; General-purpose registers:\n"); + for (i = REGIX_AX; i < REGIX_GPLIM; i++) + regdump(map, 0, + REGF_HEX | REGF_UNSGN | REGF_SGN | REGF_GPWD | REGSRC_GP | i); + regdump(map, 0, REGF_HEX | REGF_GPWD | REGSRC_GP | REGIX_IP); + + printf(";; Segment registers:\n"); + for (i = 0; i < REGIX_SEGLIM; i++) + regdump(map, 0, REGF_HEX | REGF_16 | REGSRC_SEG | i); + + printf(";; Flags:\n"); + regdump(map, 0, REGSRC_GP | REGF_GPWD | REGIX_FLAGS); +} + +void regdump_fp(const struct regmap *map) +{ + unsigned top = (map->fx->fsw >> 11)&7u; + unsigned tag = map->fx->ftw; + unsigned i; + + printf(";; Floating-point/MMX registers:\n"); + if (!top && tag == 0xff) + for (i = 0; i < 8; i++) + regdump(map, 0, + REGF_HEX | REGF_UNSGN | REGF_SGN | REGF_CHR | + REGF_32 | REGF_16 | REGF_8 | + REGSRC_STMMX | i | (6 << REGF_WDSHIFT)); + if (tag) + for (i = 0; i < 8; i++) + regdump(map, 0, REGF_FLT | REGF_80 | REGSRC_STMMX | i); + + printf(";; Floating-point state:\n"); + dump_fpflags(0, map->fx); +} + +void regdump_simd(const struct regmap *map) +{ + unsigned f = REGF_HEX | REGF_FLT | REGF_UNSGN | REGF_SGN | REGF_CHR | + REGF_64 | REGF_32 | REGF_16 | REGF_8 | + REGSRC_SIMD; + unsigned i; + + if (map->avx) f |= 8 << REGF_WDSHIFT; + else f |= 7 << REGF_WDSHIFT; + + printf(";; SSE/AVX registers:\n"); + for (i = 0; i < N(map->fx->xmm); i++) + regdump(map, 0, f | i); + + printf(";; SSE/AVX floating-point state:\n"); + dump_mxflags(0, map->fx); +} + +#endif + +/*----- ARM32 -------------------------------------------------------------*/ + +#if CPUFAM_ARMEL + +unsigned regdump__flags = 0; + +void regdump_init(void) +{ + if (cpu_feature_p(CPUFEAT_ARM_VFP)) regdump__flags |= REGF_VFP; + if (cpu_feature_p(CPUFEAT_ARM_D32)) regdump__flags |= REGF_D32; +} + +static void dump_flags(const char *lbl, unsigned f) +{ + static const char + *modetab[] = { "?00", "?01", "?02", "?03", "?04", "?05", "?06", "?07", + "?08", "?09", "?10", "?11", "?12", "?13", "?14", "?15", + "usr", "fiq", "irq", "svc", "?20", "?21", "mon", "abt", + "?24", "?25", "hyp", "und", "?28", "?29", "?30", "sys" }, + *condtab[] = { "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", + "hi", "ls", "ge", "lt", "gt", "le", "al", "nv" }; + + printf(";; "); + if (lbl) printf("%s: ", lbl); + printf(" cpsr = 0x%08x\n", f); + printf(";;\t\tuser: %cn %cz %cc %cv %cq ge=%c%c%c%c\n", + (f >> 31)&1u ? '+' : '-', + (f >> 30)&1u ? '+' : '-', + (f >> 29)&1u ? '+' : '-', + (f >> 28)&1u ? '+' : '-', + (f >> 27)&1u ? '+' : '-', + (f >> 19)&1u ? '1' : '0', + (f >> 18)&1u ? '1' : '0', + (f >> 17)&1u ? '1' : '0', + (f >> 16)&1u ? '1' : '0'); + printf(";;\t\tsystem: %cj it=%s:%c%c%c%c %ce %ca %ci %cf %ct m=%s\n", + (f >> 24)&1u ? '+' : '-', + condtab[(f >> 12)&15u], + (f >> 11)&1u ? '1' : '0', + (f >> 10)&1u ? '1' : '0', + (f >> 26)&1u ? '1' : '0', + (f >> 25)&1u ? '1' : '0', + (f >> 9)&1u ? '+' : '-', + (f >> 8)&1u ? '+' : '-', + (f >> 7)&1u ? '+' : '-', + (f >> 6)&1u ? '+' : '-', + (f >> 5)&1u ? '+' : '-', + modetab[(f >> 0)&31u]); +} + +static void dump_fpflags(const char *lbl, unsigned f) +{ + static const char *rcmap[] = { "nr", "+∞", "-∞", "0" }; + + printf(";; "); + if (lbl) printf("%s: ", lbl); + printf(" fpscr = 0x%08x\n", f); + printf(";;\t\tcond: %cn %cz %cc %cv %cqc\n", + (f >> 31)&1u ? '+' : '-', + (f >> 30)&1u ? '+' : '-', + (f >> 29)&1u ? '+' : '-', + (f >> 28)&1u ? '+' : '-', + (f >> 27)&1u ? '+' : '-'); + printf(";;\t\ttrap: %cide %cixe %cufe %cofe %cdze %cioe\n", + (f >> 15)&1u ? '+' : '-', + (f >> 12)&1u ? '+' : '-', + (f >> 11)&1u ? '+' : '-', + (f >> 10)&1u ? '+' : '-', + (f >> 9)&1u ? '+' : '-', + (f >> 8)&1u ? '+' : '-'); + printf(";;\t\terror: %cide %cixe %cufe %cofe %cdze %cioe\n", + (f >> 7)&1u ? '+' : '-', + (f >> 4)&1u ? '+' : '-', + (f >> 3)&1u ? '+' : '-', + (f >> 2)&1u ? '+' : '-', + (f >> 1)&1u ? '+' : '-', + (f >> 0)&1u ? '+' : '-'); + printf(";;\t\tcontrol: %cahp %cdn %cfz rm=%s str=%d len=%d\n", + (f >> 26)&1u ? '+' : '-', + (f >> 25)&1u ? '+' : '-', + (f >> 24)&1u ? '+' : '-', + rcmap[(f >> 22)&3u], + (f >> 20)&3u, + (f >> 16)&7u); +} + +void regdump_gp(const struct regmap *map) +{ + unsigned i; + + printf(";; General-purpose registers:\n"); + for (i = 0; i < 16; i++) + regdump(map, 0, + REGF_HEX | REGF_UNSGN | REGF_SGN | REGF_32 | REGSRC_GP | i); + + printf(";; Flags:\n"); + regdump(map, 0, REGSRC_GP | REGF_32 | REGIX_CPSR); +} + +void regdump_fp(const struct regmap *map) +{ + unsigned i, n; + + if (!(regdump__flags®F_VFP)) { + printf(";; Floating-point and SIMD not available\n"); + return; + } + + printf(";; Floating-point/SIMD registers:\n"); + if (regdump__flags®F_D32) n = 32; + else n = 16; + for (i = 0; i < n; i++) + regdump(map, 0, + REGF_HEX | REGF_UNSGN | REGF_SGN | REGF_FLT | REGF_CHR | + REGF_64 | REGF_32 | REGF_16 | REGF_8 | + REGSRC_SIMD | i | (6 << REGF_WDSHIFT)); + + printf(";; Floating-point state:\n"); + dump_fpflags(0, map->fp->fpscr); +} + +void regdump_simd(const struct regmap *map) { ; } + +#endif + +/*----- ARM64 -------------------------------------------------------------*/ + +#if CPUFAM_ARM64 + +void regdump_init(void) { ; } + +static void dump_flags(const char *lbl, unsigned f) +{ + printf(";; "); + if (lbl) printf("%s: ", lbl); + printf(" nzcv = 0x%08x\n", f); + printf(";;\t\tuser: %cn %cz %cc %cv\n", + (f >> 31)&1u ? '+' : '-', + (f >> 30)&1u ? '+' : '-', + (f >> 29)&1u ? '+' : '-', + (f >> 28)&1u ? '+' : '-'); +} + +static void dump_fpflags(const char *lbl, const struct fpsave *fp) +{ + static const char *rcmap[] = { "nr", "+∞", "-∞", "0" }; + int skip = lbl ? strlen(lbl) + 2 : 0; + + printf(";; "); + if (lbl) printf("%s: ", lbl); + printf(" fpsr = 0x%08x\n", fp->fpsr); + printf(";;\t\tcond: %cn %cz %cc %cv %cqc\n", + (fp->fpsr >> 31)&1u ? '+' : '-', + (fp->fpsr >> 30)&1u ? '+' : '-', + (fp->fpsr >> 29)&1u ? '+' : '-', + (fp->fpsr >> 28)&1u ? '+' : '-', + (fp->fpsr >> 27)&1u ? '+' : '-'); + printf(";;\t\terror: %cidc %cixc %cufc %cofc %cdzc %cioc\n", + (fp->fpsr >> 7)&1u ? '+' : '-', + (fp->fpsr >> 4)&1u ? '+' : '-', + (fp->fpsr >> 3)&1u ? '+' : '-', + (fp->fpsr >> 2)&1u ? '+' : '-', + (fp->fpsr >> 1)&1u ? '+' : '-', + (fp->fpsr >> 0)&1u ? '+' : '-'); + printf(";; %*s fpcr = 0x%08x\n", skip, "", fp->fpcr); + printf(";;\t\ttrap: %cide %cixe %cufe %cofe %cdze %cioe\n", + (fp->fpcr >> 15)&1u ? '+' : '-', + (fp->fpcr >> 12)&1u ? '+' : '-', + (fp->fpcr >> 11)&1u ? '+' : '-', + (fp->fpcr >> 10)&1u ? '+' : '-', + (fp->fpcr >> 9)&1u ? '+' : '-', + (fp->fpcr >> 8)&1u ? '+' : '-'); + printf(";;\t\tcontrol: %cahp %cdn %cfz rm=%s str=%d len=%d\n", + (fp->fpcr >> 26)&1u ? '+' : '-', + (fp->fpcr >> 25)&1u ? '+' : '-', + (fp->fpcr >> 24)&1u ? '+' : '-', + rcmap[(fp->fpcr >> 22)&3u], + (fp->fpcr >> 20)&3u, + (fp->fpcr >> 16)&7u); +} + +void regdump_gp(const struct regmap *map) +{ + unsigned i; + + printf(";; General-purpose registers:\n"); + for (i = 0; i < 32; i++) + regdump(map, 0, + REGF_HEX | REGF_UNSGN | REGF_SGN | REGF_64 | REGSRC_GP | i); + regdump(map, 0, REGF_HEX | REGF_64 | REGSRC_GP | REGIX_PC); + + printf(";; Flags:\n"); + regdump(map, 0, REGSRC_GP | REGF_32 | REGIX_NZCV); +} + +void regdump_fp(const struct regmap *map) +{ + unsigned i; + + printf(";; Floating-point/SIMD registers:\n"); + for (i = 0; i < 32; i++) + regdump(map, 0, + REGF_HEX | REGF_UNSGN | REGF_SGN | REGF_FLT | REGF_CHR | + REGF_64 | REGF_32 | REGF_16 | REGF_8 | + REGSRC_SIMD | i | (7 << REGF_WDSHIFT)); + + printf(";; Floating-point state:\n"); + dump_fpflags(0, map->fp); +} + +void regdump_simd(const struct regmap *map) { ; } + +#endif + +/*----- The main entry point ----------------------------------------------*/ + +/* --- @regdump@ --- * + * + * Arguments: @const void *base@ = pointer to base structure, corresponding + * to the @REGF_SRCMASK@ part of @f@ + * @const char *lbl@ = label to print + * @uint32 f@ = format control word; see @REGF_...@ + * + * Returns: --- + * + * Use: Dump a register value, or chunk of memory. + * + * This function is not usually called directly; instead, use + * the `reg' or `mem' assembler macros. + */ + +void regdump(const void *base, const char *lbl, uint32 f) +{ + unsigned ix = (f®F_IXMASK) >> REGF_IXSHIFT; + unsigned wd = 1 << ((f®F_WDMASK) >> REGF_WDSHIFT); + unsigned fmt, ty; + uint32 fmtbit, tybit; + const void *p; + char regbuf[8]; const char *reg = regname(regbuf, f); + const struct regmap *map; + const struct fmttab *tab; + struct fmtinfo fi; + int firstp = 1; + int skip; + size_t n; + +#if CPUFAM_X86 || CPUFAM_AMD64 + union vreg vr; +#endif + + if (reg) { + n = strlen(reg); + if (n < 7) { + memmove(regbuf + 7 - n, reg, n + 1); + memset(regbuf, ' ', 7 - n); + } + } + + switch (f®F_SRCMASK) { + case REGSRC_ABS: + p = base; + break; + +#if CPUFAM_X86 || CPUFAM_AMD64 + case REGSRC_GP: + map = (const struct regmap *)base; + if (ix == REGIX_FLAGS && !(f®F_FMTMASK)) + { dump_flags(lbl, reg, map->gp->gp[REGIX_FLAGS]); return; } + p = &map->gp->gp[ix]; + break; + case REGSRC_SEG: + map = (const struct regmap *)base; + assert(wd == 1); assert((f®F_TYMASK) == REGF_16); + p = &map->gp->seg[ix]; + break; + case REGSRC_STMMX: + map = (const struct regmap *)base; + if (ix == REGIX_FPFLAGS) + { assert(!(f®F_FMTMASK)); dump_fpflags(lbl, map->fx); return; } + if (!((map->fx->ftw << ix)&128u)) { + printf(";; "); + if (lbl) printf("%s: ", lbl); + if (reg) printf("%s = ", reg); + printf(" dead\n"); + return; + } + p = &map->fx->stmmx[ix]; + break; + case REGSRC_SIMD: + map = (const struct regmap *)base; + if (ix == REGIX_FPFLAGS) + { assert(!(f®F_FMTMASK)); dump_mxflags(lbl, map->fx); return; } + if (wd <= 128) + p = &map->fx->xmm[ix]; + else { + vr.v128[0] = map->fx->xmm[ix]; + vr.v128[1] = map->avx->ymmh[ix]; + assert(wd == 256); + p = &vr; + } + break; +#endif + +#if CPUFAM_ARMEL + case REGSRC_GP: + map = (const struct regmap *)base; + if (ix == REGIX_CPSR && !(f®F_FMTMASK)) + { dump_flags(lbl, map->gp->r[REGIX_CPSR].u32); return; } + p = &map->gp->r[ix]; + break; + case REGSRC_FP: + case REGSRC_SIMD: + map = (const struct regmap *)base; + if (ix == REGIX_FPSCR) { + assert(!(f®F_FMTMASK)); + dump_fpflags(lbl, map->fp->fpscr); + return; + } + switch (regwd(f)) { + case 32: p = &map->fp->u.s[ix]; break; + case 64: p = &map->fp->u.d[ix]; break; + case 128: p = &map->fp->u.q[ix]; break; + default: assert(0); + } + break; +#endif + +#if CPUFAM_ARM64 + case REGSRC_GP: + map = (const struct regmap *)base; + if (ix == REGIX_NZCV && !(f®F_FMTMASK)) + { dump_flags(lbl, map->gp->r[REGIX_NZCV].u64); return; } + p = &map->gp->r[ix]; + break; + case REGSRC_FP: + case REGSRC_SIMD: + map = (const struct regmap *)base; + if (ix == REGIX_FPFLAGS) + { assert(!(f®F_FMTMASK)); dump_fpflags(lbl, map->fp); return; } + p = &map->fp->v[ix]; + break; +#endif + + default: + assert(0); + } + + skip = (lbl ? strlen(lbl) + 2 : 0) + (reg ? strlen(reg) : 0); + fi.f = 0; if (wd > 1) fi.f |= FMTF_VECTOR; + + for (ty = (f®F_TYMASK) >> REGF_TYSHIFT, + tybit = 1 << REGF_TYSHIFT; + ty; + ty >>= 1, tybit <<= 1) { + if (!(ty&1u)) continue; + + for (fmt = (f®F_FMTMASK) >> REGF_FMTSHIFT, + fmtbit = 1 << REGF_FMTSHIFT; + fmt; + fmt >>= 1, fmtbit <<= 1) { + + if (!(fmt&1u)) continue; + + for (tab = fmttab; tab->mask; tab++) + if (tab->mask == (fmtbit | tybit)) goto found; + continue; + found: + + if (firstp) { + printf(";;"); + if (lbl) printf(" %s:", lbl); + if (reg) printf(" %s =", reg); + firstp = 0; + } else if (wd > 1) + printf("\n;; %*s =", skip, ""); + else + fputs(" =", stdout); + + fi.p = p; fi.wd = 0; + while (fi.wd < wd) { putchar(' '); tab->fmt(&fi); } + } + } + putchar('\n'); +} + +/*----- Other random utilities --------------------------------------------*/ + +/* --- @regdump_freshline@ --- * + * + * Arguments: --- + * + * Returns: --- + * + * Use: Begin a fresh line of output. + */ + +void regdump_freshline(void) { putchar('\n'); } + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/base/regdump.h b/base/regdump.h new file mode 100644 index 00000000..bbbd5bd1 --- /dev/null +++ b/base/regdump.h @@ -0,0 +1,941 @@ +/* -*-c-*- + * + * Register dump and debugging support + * + * (c) 2019 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef CATACOMB_REGDUMP_H +#define CATACOMB_REGDUMP_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include "config.h" + +#ifndef ENABLE_ASM_DEBUG +# error "Assembler-level debug disabled by `configure' script." +#endif + +#if __ASSEMBLER__ +# include "asm-common.h" +#else +# include +# include +#endif + +/*----- Random utilities --------------------------------------------------*/ + +#define DO8(_) \ + _(0) _(1) _(2) _(3) _(4) _(5) _(6) _(7) +#define DOHI8(_) \ + _(8) _(9) _(10) _(11) _(12) _(13) _(14) _(15) + +#define DO16(_) DO8(_) DOHI8(_) + +#define DO32(_) \ + DO16(_) \ + _(16) _(17) _(18) _(19) _(20) _(21) _(22) _(23) \ + _(24) _(25) _(26) _(27) _(28) _(29) _(30) _(31) + +/*----- Common data structures --------------------------------------------*/ + +#if !__ASSEMBLER__ + +/* The following are good on our assembler targets. */ +typedef signed char int8; +typedef short int16; +typedef int int32; +#if LONG_MAX >> 31 > 0x7fffffff + typedef long int64; +#else + typedef long long int64; +#endif +typedef float float32; +typedef double float64; +typedef long double float80; + +#if CPUFAM_X86 || CPUFAM_ARMEL +# define PTR32 void *p; +# define PTR64 +#endif +#if CPUFAM_AMD64 || CPUFAM_ARM64 +# define PTR32 +# define PTR64 void *p; +#endif + +#define SIMD_COMMON(wd) \ + uint8 u8[wd/8]; \ + int8 i8[wd/8]; \ + uint16 u16[wd/16]; \ + int16 i16[wd/16]; \ + uint32 u32[wd/32]; \ + int32 i32[wd/32]; \ + uint64 u64[wd/64]; \ + int64 i64[wd/64]; \ + float32 f32[wd/32]; \ + float64 f64[wd/64] + +union gp32 { uint32 u32; int32 i32; PTR32 }; +union gp64 { uint64 u64; int64 i64; PTR64 }; + +#endif + +/*----- Format word layout ------------------------------------------------*/ + +#define REGF_IXMASK 0x000000ff +#define REGF_IXSHIFT 0 +/* The index into the vector indicated by `REGF_SRCMASK', if applicable. */ + +#define REGF_FMTMASK 0x0000ff00 +#define REGF_FMTSHIFT 8 +#define REGF_HEX 0x00000100 +#define REGF_CHR 0x00000200 +#define REGF_FLT 0x00000400 +#define REGF_UNSGN 0x00000800 +#define REGF_SGN 0x00001000 +/* How to format the value(s) found. */ + +#define REGF_TYMASK 0x00ff0000 +#define REGF_TYSHIFT 16 +#define REGF_80 0x00010000 +#define REGF_64 0x00020000 +#define REGF_32 0x00040000 +#define REGF_16 0x00080000 +#define REGF_8 0x00100000 +/* Size of the value(s) to dump. */ + +#define REGF_SRCMASK 0x0f000000 +#define REGSRC_ABS 0x01000000 /* absolute address */ +#define REGSRC_GP 0x02000000 /* general-purpose register */ +#define REGSRC_FP 0x03000000 /* floating-point register */ +#define REGSRC_SIMD 0x04000000 /* SIMD vector register */ +#define REGSRC_STMMX 0x05000000 /* x86-specific: x87/MMX register */ +#define REGSRC_SEG 0x06000000 /* x86-specific: segment register */ +/* Where to find the values. */ + +#define REGF_WDMASK 0xf0000000 +#define REGF_WDSHIFT 28 +/* If we're to print a scalar, this is zero; otherwise, log_2 of the vector + * register width, in bits. + */ + +/*----- x86 and AMD64 -----------------------------------------------------*/ + +#if CPUFAM_X86 || CPUFAM_AMD64 + +#define REGIX_FLAGS 0 +#define REGIX_IP 1 +#define REGIX_ADDR 2 +#define REGIX_AX 3 +#define REGIX_BX 4 +#define REGIX_CX 5 +#define REGIX_DX 6 +#define REGIX_SI 7 +#define REGIX_DI 8 +#define REGIX_BP 9 +#define REGIX_SP 10 +#if CPUFAM_X86 +# define REGIX_GPLIM 11 +#endif +#if CPUFAM_AMD64 +# define REGIX_R8 11 +# define REGIX_R9 12 +# define REGIX_R10 13 +# define REGIX_R11 14 +# define REGIX_R12 15 +# define REGIX_R13 16 +# define REGIX_R14 17 +# define REGIX_R15 18 +# define REGIX_GPLIM 19 +#endif + +#define REGIX_CS 0 +#define REGIX_DS 1 +#define REGIX_SS 2 +#define REGIX_ES 3 +#define REGIX_FS 4 +#define REGIX_GS 5 +#define REGIX_SEGLIM 6 + +#define REGIX_FPFLAGS 255 + +#if !__ASSEMBLER__ + +#if CPUFAM_X86 +typedef union gp32 gpreg; +#endif +#if CPUFAM_AMD64 +typedef union gp64 gpreg; +#endif + +struct gpsave { + gpreg gp[REGIX_GPLIM]; + uint16 seg[REGIX_SEGLIM]; +}; + +union stmmx { + SIMD_COMMON(64); +#if FLT_RADIX == 2 && LDBL_MANT_DIG == 64 + long double f80; +#endif +unsigned char _pad[16]; +}; + +union xmm { SIMD_COMMON(128); }; +union ymm { SIMD_COMMON(256); }; +union vreg { union xmm v128[2]; union ymm v256; }; + +struct fxsave { + unsigned short fcw; + unsigned short fsw; + unsigned char ftw; + unsigned char _res0; + unsigned short fop; +#if CPUFAM_X86 + unsigned int fpu_ip; + unsigned short fpu_cs; + unsigned short _res1; + unsigned int fpu_dp; + unsigned short fpu_ds; + unsigned short _res2; +#endif +#if CPUFAM_AMD64 + unsigned long long fpu_ip; + unsigned long long fpu_dp; +#endif + unsigned int mxcsr; + unsigned int mxcsr_mask; + + union stmmx stmmx[8]; + +#if CPUFAM_X86 + union xmm xmm[8]; + unsigned char _pad0[8*16]; +#endif +#if CPUFAM_AMD64 + union xmm xmm[16]; +#endif + + unsigned char _pad1[96]; +}; + +struct xsave_avx { +#if CPUFAM_X86 + union xmm ymmh[8]; + unsigned char _pad0[8*16]; +#endif +#if CPUFAM_AMD64 + union xmm ymmh[16]; +#endif +}; + +struct regmap { + struct gpsave *gp; + struct fxsave *fx; + struct xsave_avx *avx; +}; + +#else + + .extern regdump_gpsave + .extern regdump_xtsave + .extern regdump_xtrstr + .extern regdump_gprstr + + regmap_gp = 0*WORDSZ + regmap_fx = 1*WORDSZ + regmap_avx = 2*WORDSZ + regmap_size = 3*WORDSZ + +#define REGDEF_GPX86_COMMON(rn, RN) \ + regsrc.e##rn = REGSRC_GP | REGIX_##RN; \ + regty.e##rn = REGF_32; \ + regfmt.e##rn = REGF_HEX; \ + regsrc.r##rn = REGSRC_GP | REGIX_##RN; \ + regty.r##rn = REGF_64; \ + regfmt.r##rn = REGF_HEX + +#define REGDEF_GPX86_ABCD(rn, RN) \ + regsrc.rn##hl = (4 << REGF_WDSHIFT) | REGSRC_GP | REGIX_##RN##X; \ + regty.rn##hl = REGF_8; \ + regfmt.rn##hl = REGF_HEX; \ + regsrc.rn##l = REGSRC_GP | REGIX_##RN##X; \ + regty.rn##l = REGF_8; \ + regfmt.rn##l = REGF_HEX; \ + regsrc.rn##x = REGSRC_GP | REGIX_##RN##X; \ + regty.rn##x = REGF_16; \ + regfmt.rn##x = REGF_HEX; \ + REGDEF_GPX86_COMMON(rn##x, RN##X) +REGDEF_GPX86_ABCD(a, A) +REGDEF_GPX86_ABCD(b, B) +REGDEF_GPX86_ABCD(c, C) +REGDEF_GPX86_ABCD(d, D) + + regsrc.eflags = REGSRC_GP | REGIX_FLAGS + regty.eflags = REGF_32 + regfmt.eflags = 0 + +#if CPUFAM_AMD64 + regsrc.rflags = REGSRC_GP | REGIX_FLAGS + regty.rflags = REGF_64 + regfmt.rflags = 0 +#endif + +#define REGDEF_GPX86_XP(rn, RN) \ + regsrc.rn##l = REGSRC_GP | REGIX_##RN; \ + regty.rn##l = REGF_8; \ + regfmt.rn##l = REGF_HEX; \ + regsrc.rn = REGSRC_GP | REGIX_##RN; \ + regty.rn = REGF_16; \ + regfmt.rn = REGF_HEX; \ + REGDEF_GPX86_COMMON(rn, RN) +REGDEF_GPX86_XP(ip, IP) +REGDEF_GPX86_XP(si, SI) +REGDEF_GPX86_XP(di, DI) +REGDEF_GPX86_XP(bp, BP) +REGDEF_GPX86_XP(sp, SP) + +#if CPUFAM_AMD64 +# define REGDEF_GPAMD64(i) \ + regsrc.r##i##b = REGSRC_GP | REGIX_R##i; \ + regty.r##i##b = REGF_8; \ + regfmt.r##i##b = REGF_HEX; \ + regsrc.r##i##w = REGSRC_GP | REGIX_R##i; \ + regty.r##i##w = REGF_16; \ + regfmt.r##i##w = REGF_HEX; \ + regsrc.r##i##d = REGSRC_GP | REGIX_R##i; \ + regty.r##i##d = REGF_32; \ + regfmt.r##i##d = REGF_HEX; \ + regsrc.r##i = REGSRC_GP | REGIX_R##i; \ + regty.r##i = REGF_64; \ + regfmt.r##i = REGF_HEX; + DOHI8(REGDEF_GPAMD64) +#endif + +#define REGDEF_SEG(rn, RN) \ + regsrc.rn = REGSRC_SEG | REGIX_##RN; \ + regty.rn = REGF_16; \ + regfmt.rn = REGF_HEX +REGDEF_SEG(ss, SS) +REGDEF_SEG(cs, CS) +REGDEF_SEG(ds, DS) +REGDEF_SEG(es, ES) +REGDEF_SEG(fs, FS) +REGDEF_SEG(gs, GS) + +#define REGDEF_STMMX(i) \ + regsrc.st##i = REGSRC_STMMX | i; \ + regty.st##i = REGF_80; \ + regfmt.st##i = REGF_FLT; \ + regsrc.mm##i = (6 << REGF_WDSHIFT) | REGSRC_STMMX | i; \ + regty.mm##i = REGF_16; \ + regfmt.mm##i = REGF_HEX; +DO8(REGDEF_STMMX) + +#define REGDEF_SIMD(i) \ + regsrc.xmm##i = (7 << REGF_WDSHIFT) | REGSRC_SIMD | i; \ + regty.xmm##i = REGF_32; \ + regfmt.xmm##i = REGF_HEX; \ + regsrc.ymm##i = (8 << REGF_WDSHIFT) | REGSRC_SIMD | i; \ + regty.ymm##i = REGF_32; \ + regfmt.ymm##i = REGF_HEX; +DO8(REGDEF_SIMD) +#if CPUFAM_AMD64 + DOHI8(REGDEF_SIMD) +#endif + + REGDUMP_GPSIZE = REGIX_GPLIM*WORDSZ + REGIX_SEGLIM*2 + +# if CPUFAM_AMD64 && ABI_SYSV + REGDUMP_SPADJ = REGDUMP_GPSIZE + WORDSZ + 128 +# else + REGDUMP_SPADJ = REGDUMP_GPSIZE + WORDSZ +# endif + +.macro _saveregs addr=nil + // Save the registers, leaving r/ebp pointing to the register map. + + // Stash r/eax. This is bletcherous: hope we don't get a signal in + // the next few instructions. + mov [R_sp(r) - REGDUMP_SPADJ + (REGIX_AX - 1)*WORDSZ], R_a(r) + + .ifnes "\addr", "nil" + // Collect the effective address for the following dump, leaving it + // in the `addr' slot of the dump. + lea R_a(r), \addr + mov [R_sp(r) - REGDUMP_SPADJ + (REGIX_ADDR - 1)*WORDSZ], R_a(r) + .endif + + // Make space for the register save area. On AMD64 with System/V + // ABI, also skip the red zone. Use `lea' here to preserve the + // flags. + lea R_sp(r), [R_sp(r) - REGDUMP_SPADJ] + + // Save flags and general-purpose registers. On 32-bit x86, we save + // ebx here and establish a GOT pointer here for the benefit of the + // PLT-indirect calls made later on. + pushf +# if CPUFAM_X86 + mov [esp + 4*REGIX_BX], ebx + ldgot +# endif + callext F(regdump_gpsave) + + // Make space for the extended registers. + sub R_sp(r), R_c(r) + callext F(regdump_xtsave) + + // Prepare for calling back into C. On 32-bit x86, leave space for + // the arguments and set up the GOT pointer; on AMD64 Windows, leave + // the `shadow space' for the called-function's arguments. Also, + // forcibly align the stack pointer to a 16-byte boundary. +# if CPUFAM_X86 + sub esp, 16 +# elif ABI_WIN + sub rsp, 32 +# endif + and R_sp(r), ~15 +.endm + +.macro _rstrregs + // Restore registers. + + // We assume r/ebp still points to the register map. + callext F(regdump_xtrstr) + mov R_sp(r), R_bp(r) + callext F(regdump_gprstr) + popf + lea R_sp(r), [R_sp(r) + REGDUMP_SPADJ] +.endm + +.macro _regbase +# if CPUFAM_X86 + mov [esp + 0], ebp +# elif ABI_SYSV + mov rdi, rbp +# elif ABI_WIN + mov rcx, rbp +# endif +.endm + +.macro _membase + mov R_a(r), [R_bp(r) + regmap_gp] +# if CPUFAM_X86 + mov eax, [eax + REGIX_ADDR*WORDSZ] + mov [esp + 0], eax +# elif ABI_SYSV + mov rdi, [rax + REGIX_ADDR*WORDSZ] +# elif ABI_WIN + mov rcx, [rax + REGIX_ADDR*WORDSZ] +# endif +.endm + +.macro _reglbl msg + .ifeqs "\msg", "" +# if CPUFAM_X86 + mov dword ptr [esp + 4], 0 +# elif ABI_SYSV + xor esi, esi +# elif ABI_WIN + xor edx, edx +# endif + .else +# if CPUFAM_X86 + lea eax, [INTADDR(.L$_reglbl$\@)] + mov [esp + 4], eax +# elif ABI_SYSV + lea rsi, [INTADDR(.L$_reglbl$\@)] +# elif ABI_WIN + lea rdx, [INTADDR(.L$_reglbl$\@)] +# endif + _LIT +.L$_reglbl$\@: + .asciz "\msg" + _ENDLIT + .endif +.endm + +.macro _regfmt arg +# if CPUFAM_X86 + mov dword ptr [esp + 8], \arg +# elif ABI_SYSV + mov edx, \arg +# elif ABI_WIN + mov r8d, \arg +# endif +.endm + +#endif + +#endif + +/*----- ARM32 -------------------------------------------------------------*/ + +#if CPUFAM_ARMEL + +#if !__ASSEMBLER__ +extern unsigned regdump__flags; +#endif +#define REGF_VFP 1u +#define REGF_D32 2u + +#define REGIX_CPSR 16 +#define REGIX_ADDR 17 +#define REGIX_GPLIM 18 + +#define REGIX_FPSCR 255 + +#if !__ASSEMBLER__ + +union neon64 { SIMD_COMMON(64); }; +union neon128 { SIMD_COMMON(128); }; + +struct gpsave { union gp32 r[REGIX_GPLIM]; }; + +struct fpsave { + unsigned fpscr; + unsigned _pad0; + union { + float32 s[32]; + union neon64 d[32]; + union neon128 q[16]; + } u; +}; + +struct regmap { + struct gpsave *gp; + struct fpsave *fp; +}; + +#else + + .extern regdump_gpsave + .extern regdump_xtsave + .extern regdump_xtrstr + .extern regdump_gprstr + + regmap_gp = 0 + regmap_fp = 4 + regmap_size = 8 + +#define REGDEF_GP(i) \ + regsrc.r##i = REGSRC_GP | i; \ + regty.r##i = REGF_32; \ + regfmt.r##i = REGF_HEX; +DO16(REGDEF_GP) + + regsrc.cpsr = REGSRC_GP | REGIX_CPSR + regty.cpsr = REGF_32 + regfmt.cpsr = 0 + +#define REGDEF_NEONS(i) \ + regsrc.s##i = REGSRC_FP | i; \ + regty.s##i = REGF_32; \ + regfmt.s##i = REGF_FLT; +DO32(REGDEF_NEONS) + +#define REGDEF_NEOND(i) \ + regsrc.d##i = (6 << REGF_WDSHIFT) | REGSRC_FP | i; \ + regty.d##i = REGF_32; \ + regfmt.d##i = REGF_HEX; +DO32(REGDEF_NEOND) + +#define REGDEF_NEONQ(i) \ + regsrc.q##i = (7 << REGF_WDSHIFT) | REGSRC_FP | i; \ + regty.q##i = REGF_32; \ + regfmt.q##i = REGF_HEX; +DO16(REGDEF_NEONQ) + + regsrc.fpscr = REGSRC_FP | REGIX_FPSCR + regty.fpscr = REGF_32 + regfmt.fpscr = 0 + + REGDUMP_GPSIZE = 4*REGIX_GPLIM + REGDUMP_FPSIZE_D16 = 8 + 16*8 + REGDUMP_FPSIZE_D32 = 8 + 32*8 + +.macro _saveregs base=nil, off=#0 + // Save the registers, leaving r4 pointing to the register map. + + // Stash r14. This is bletcherous: hope we don't get a signal in + // the next few instructions. + str r14, [r13, #-REGDUMP_GPSIZE + 14*4] + + .ifnes "\base,\off", "nil,#0" + // Collect the effective address for the following dump, leaving it + // in the `addr' slot of the dump. + .ifeqs "\base", "nil" + adrl r14, \off + .else + add r14, \base, \off + .endif + str r14, [r13, #-REGDUMP_GPSIZE + 4*REGIX_ADDR] + .endif + + // Make space for the register save area. + sub r13, r13, #REGDUMP_GPSIZE + + // Save flags and general-purpose registers. + str r12, [r13, #4*12] + bl regdump_gpsave + + // Make space for the extended registers. + sub r13, r13, r0 + bl regdump_xtsave + + // Prepare for calling back into C. + ldgot + mov r0, r13 + bic r0, r0, #15 + mov r13, r0 +.endm + +.macro _rstrregs + // Restore registers. + + // We assume r4 still points to the register map. + bl regdump_xtrstr + mov r13, r4 + bl regdump_gprstr + ldr r14, [r13, #14*4] + add r13, r13, #REGDUMP_GPSIZE +.endm + +.macro _regbase + mov r0, r5 +.endm + +.macro _membase + mov r0, r6 +.endm + +.macro _reglbl msg + adrl r1, .L$_reglbl$\@ + _LIT +.L$_reglbl$\@: + .asciz "\msg" + .balign 4 + _ENDLIT +.endm + +.macro _regfmt arg + movw r2, #\arg&0xffff + movt r2, #(\arg >> 16)&0xffff +.endm + +#endif + +#endif + +/*----- ARM64 -------------------------------------------------------------*/ + +#if CPUFAM_ARM64 + +#define REGIX_NZCV 32 +#define REGIX_PC 33 +#define REGIX_ADDR 34 +#define REGIX_GPLIM 36 + +#define REGIX_FPFLAGS 255 + +#if !__ASSEMBLER__ + +union v128 { SIMD_COMMON(128); }; + +struct gpsave { union gp64 r[REGIX_GPLIM]; }; + +struct fpsave { + unsigned fpsr, fpcr; + union v128 v[32]; +}; + +struct regmap { + struct gpsave *gp; + struct fpsave *fp; +}; + +#else + + .extern regdump_gpsave + .extern regdump_xtsave + .extern regdump_xtrstr + .extern regdump_gprstr + + regmap_gp = 0 + regmap_fp = 8 + regmap_size = 16 + +#define REGDEF_GP(i) \ + regsrc.x##i = REGSRC_GP | i; \ + regty.x##i = REGF_64; \ + regfmt.x##i = REGF_HEX; \ + regsrc.w##i = REGSRC_GP | i; \ + regty.w##i = REGF_32; \ + regfmt.w##i = REGF_HEX; +DO32(REGDEF_GP) + + regsrc.sp = REGSRC_GP | 31 + regty.sp = REGF_64 + regfmt.sp = REGF_HEX + + regsrc.pc = REGSRC_GP | REGIX_PC + regty.pc = REGF_64 + regfmt.pc = REGF_HEX + + regsrc.nzcv = REGSRC_GP | REGIX_NZCV + regty.nzcv = REGF_32 + regfmt.nzcv = 0 + +#define REGDEF_FP(i) \ + regsrc.b##i = REGSRC_FP | i; \ + regty.b##i = REGF_8; \ + regfmt.b##i = REGF_HEX; \ + regsrc.h##i = REGSRC_FP | i; \ + regty.h##i = REGF_16; \ + regfmt.h##i = REGF_HEX; \ + regsrc.s##i = REGSRC_FP | i; \ + regty.s##i = REGF_32; \ + regfmt.s##i = REGF_FLT; \ + regsrc.d##i = REGSRC_FP | i; \ + regty.d##i = REGF_64; \ + regfmt.d##i = REGF_FLT; \ + regsrc.v##i = (7 << REGF_WDSHIFT) | REGSRC_FP | i; \ + regty.v##i = REGF_32; \ + regfmt.v##i = REGF_HEX; +DO32(REGDEF_FP) + + regsrc.fpflags = REGSRC_FP | REGIX_FPFLAGS + regty.fpflags = REGF_32 + regfmt.fpflags = 0 + + REGDUMP_GPSIZE = 8*REGIX_GPLIM + REGDUMP_FPSIZE = 16 + 16 + 32*16 + +.macro _saveregs base=nil, off=#0 + // Save the registers, leaving x20 pointing to the register map. + + // Stash x30. This is bletcherous: hope we don't get a signal in + // the next few instructions. + str x30, [sp, #-REGDUMP_GPSIZE + 30*8] + + .ifnes "\base,\off", "nil,#0" + // Collect the effective address for the following dump, leaving it + // in the `addr' slot of the dump. + .ifeqs "\base", "nil" + adr x30, \off + .else + add x30, \base, \off + .endif + str x30, [sp, #-REGDUMP_GPSIZE + 8*REGIX_ADDR] + .endif + + // Make space for the register save area. + sub sp, sp, #REGDUMP_GPSIZE + + // Save flags and general-purpose registers. + stp x16, x17, [sp, #8*16] + bl regdump_gpsave + + // Make space for the extended registers. + sub sp, sp, x0 + bl regdump_xtsave +.endm + +.macro _rstrregs + // Restore registers. + + // We assume x21 still points to the register map. + bl regdump_xtrstr + mov sp, x20 + bl regdump_gprstr + ldr x30, [sp, #30*8] + add sp, sp, #REGDUMP_GPSIZE +.endm + +.macro _regbase + mov x0, x21 +.endm + +.macro _membase + mov x0, x22 +.endm + +.macro _reglbl msg + adr x1, .L$_reglbl$\@ + _LIT +.L$_reglbl$\@: + .asciz "\msg" + .balign 4 + _ENDLIT +.endm + +.macro _regfmt arg + movz w2, #\arg&0xffff + movk w2, #(\arg >> 16)&0xffff, lsl #16 +.endm + +#endif + +#endif + +/*----- Functions provided ------------------------------------------------*/ + +/* --- @regdump_init@ --- * + * + * Arguments: --- + * + * Returns: --- + * + * Use: Performs one-time initialization for register dumping. In + * particular, this performs CPU feature detection on platforms + * where that is a difficult task: without it, registers + * corresponding to optional architectural features can be + * neither printed nor preserved by the register-dump machinery. + */ + +#if !__ASSEMBLER__ +extern void regdump_init(void); +#endif + +/* --- @regdump@ --- * + * + * Arguments: @const void *base@ = pointer to base structure, corresponding + * to the @REGF_SRCMASK@ part of @f@ + * @const char *lbl@ = label to print + * @uint32 f@ = format control word; see @REGF_...@ + * + * Returns: --- + * + * Use: Dump a register value, or chunk of memory. + * + * This function is not usually called directly; instead, use + * the `reg' or `mem' assembler macros. + */ + +#if !__ASSEMBLER__ +extern void regdump(const void *base, const char *lbl, uint32 f); +#else + .extern regdump +#endif + +/* --- @regdump_gp@, @regdump_fp@, @regdump_simd@ --- * + * + * Arguments: @const struct regmap *map@ = pointer to register map + * + * Returns: --- + * + * Use: Dump the general-purpose/floating-point/SIMD registers. + * + * This function is not usually called directly; instead, use + * the `regdump' assembler macro. + */ + +#if !__ASSEMBLER__ +extern void regdump_gp(const struct regmap */*map*/); +extern void regdump_fp(const struct regmap */*map*/); +extern void regdump_simd(const struct regmap */*map*/); +#else + .extern regdump_gp + .extern regdump_fp + .extern regdump_simd +#endif + +/* --- @regdump_freshline@ --- * + * + * Arguments: --- + * + * Returns: --- + * + * Use: Begin a fresh line of output. + */ + +#if !__ASSEMBLER__ +extern void regdump_freshline(void); +#else + .extern regdump_freshline +#endif + +/*----- Main user interface macros ----------------------------------------*/ + +#if __ASSEMBLER__ + +.macro terpri + _saveregs + callext F(regdump_freshline) + _rstrregs +.endm + +.macro reg lbl, rn, fmt=0 + _saveregs + _regbase + _reglbl "\lbl" + .L$reg.fmt$\@ = regsrc.\rn | \fmt | \ + (((\fmt®F_TYMASK) == 0)®ty.\rn) | \ + (((\fmt®F_FMTMASK) == 0)®fmt.\rn) + _regfmt .L$reg.fmt$\@ + callext F(regdump) + _rstrregs +.endm + +.macro mem lbl, addr, fmt=0 + _saveregs \addr + _membase + _reglbl "\lbl" + .L$mem.fmt$\@ = REGSRC_ABS | \fmt | \ + (((\fmt®F_TYMASK) == 0)®F_32) | \ + (((\fmt®F_FMTMASK) == 0)®F_HEX) + _regfmt .L$mem.fmt$\@ + callext F(regdump) + _rstrregs +.endm + +.macro regdump gp=nil, fp=nil, simd=nil + _saveregs + .ifnes "\gp", "nil" + _regbase + callext F(regdump_gp) + .endif + .ifnes "\fp", "nil" + _regbase + callext F(regdump_fp) + .endif + .ifnes "\simd", "nil" + _regbase + callext F(regdump_simd) + .endif + _rstrregs +.endm + +#endif + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/base/rsvr.c b/base/rsvr.c new file mode 100644 index 00000000..a468db76 --- /dev/null +++ b/base/rsvr.c @@ -0,0 +1,481 @@ +/* -*-c-*- + * + * Reservoir and buffer handling + * + * (c) 2017 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include +#include +#include + +#include "rsvr.h" + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @rsvr_mkplan@ --- * + * + * Arguments: @rsvr_plan *plan@ = pointer to plan to fill in + * @const rsvr_policy *pol@ = reservoir policy to follow + * @size_t used@ = amount of data in the reservoir + * @size_t insz@ = amount of fresh input data arriving + * + * Returns: --- + * + * Use: Prepares a plan for feeding input data into a block-oriented + * operation. + * + * The caller's code for following the plan proceeds in four + * parts. + * + * 1. Insert the first @plan->head@ input items into the + * reservoir; there will be sufficient space, and + * @plan->head@ will be at most @pol->blksz@. + * + * 2. Process the first @plan->from_rsvr@ items from the + * reservoir, shifting the remaining items forward; + * @plan->from_rsvr@ will be a multiple of @pol->blksz@. + * + * 3. Process the next @plan->from_input@ items directly from + * the input; @plan->from_input@ will be a multiple of + * @pol->blksz@. + * + * 4. Insert the remaining @plan->tail@ input items into the + * reservoir for next time. + */ + +void rsvr_mkplan(rsvr_plan *plan, const rsvr_policy *pol, + size_t used, size_t insz) +{ + unsigned extra = !!(pol->f&RSVRF_FULL); + unsigned n, final; + + if (insz < pol->rsvrsz - used + extra) { + /* Easy case: there's enough space in the reservoir for the whole input, + * so just accumulate it and we're done. + */ + + plan->head = insz; + plan->from_rsvr = plan->from_input = plan->tail = 0; + } else { + /* The hard case. We're going to have to actually process something. */ + + /* Firstly, we top the reservoir up to the next block boundary. */ + n = (pol->rsvrsz - used)%pol->blksz; + plan->head = n; used += n; insz -= n; + + /* Next, figure out the final amount we'll leave in the reservoir. This + * will be congruent to USED, modulo the block size, and within the last + * BLKSZ-wide interval permitted. We must have enough material to get + * here, or we'd be in the other branch above. + */ + final = pol->rsvrsz - pol->blksz + extra + + (insz + pol->blksz - extra)%pol->blksz; + + /* If we don't have enough input to drain the reservoir completely, and + * then top it up to the necessary level, then take as much as we can + * from the reservoir; otherwise, drain completely and then use up the + * remaining input directly. + */ + if (insz < final) { + /* We don't have enough input to drain the reservoir completely and + * then top it up to the necessary final level. Take what we can. + */ + + plan->from_rsvr = used + insz - final; + plan->from_input = 0; + plan->tail = insz; + } else { + /* We have lots of input. Drain the reservoir fully, process the bulk + * of the input buffer, and load the rest into the reservoir at the + * end. + */ + + plan->from_rsvr = used; + plan->from_input = insz - final; + plan->tail = final; + } + } +} + +/* --- @rsvr_setup@ --- * + * + * Arguments: @rsvr_state *st@ = pointer to state structure to fill in + * @const rsvr_policy *pol@ = reservoir policy to follow + * @void *rsvr@ = pointer to the actual reservoir + * @unsigned *used@ = pointer to the reservoir level + * @const void *in@ = pointer to the input data + * @size_t insz@ = size of the input + * + * Returns: --- + * + * Use: Prepares for a simple operation. This performs the initial + * copy of input data into the reservoir, and prepares for the + * next step. + * + * After this, the calling code should usually proceed as + * follows. + * + * 1. Call @RSVR_NEXT@ in a sequence of loops, with + * successively smaller values of @n@, to process waiting + * data from the reservoir. Usually, each @n@ will be some + * multiple of the block size @pol->blksz@, and the final + * loop will have @n = pol->blksz@. + * + * 2. Call @rsvr_done@ to indicate that this has been done. + * + * 3. Call @RSVR_NEXT@ in a sequence of loops, as in step 1, + * to process the remaining data from the input buffer. + * + * 4. Call @rsvr_done@ to indicate that the job is complete. + */ + +void rsvr_setup(rsvr_state *st, const rsvr_policy *pol, + void *rsvr, unsigned *used, const void *in, size_t insz) +{ + rsvr_mkplan(&st->plan, pol, *used, insz); + st->rsvr = rsvr; st->in = in; st->used = used; + + if (st->plan.head) { + memcpy(rsvr + *st->used, st->in, st->plan.head); + *st->used += st->plan.head; st->in += st->plan.head; + } + st->src = RSVRSRC_RSVR; st->p = st->rsvr; st->sz = st->plan.from_rsvr; +} + +/* --- @RSVR_NEXT@, @rsvr_next@ --- * + * + * Arguments: @rsvr_state *st@ = pointer to the state structure + * @size_t n@ = amount of input data required, in bytes; should + * usually be a multiple of @pol->blksz@ + * + * Returns: A pointer to the next @n@ bytes of input, or null if there is + * insufficient data remaining. + */ + +const void *rsvr_next(rsvr_state *st, size_t n) { return RSVR_NEXT(st, n); } + +/* --- @rsvr_done@ --- * + * + * Arguments: @rsvr_state *st@ = pointer to the state structure + * + * Returns: Zero after the first pass, nonzero after the second. + * + * Use: Reports that the first or second stage (see @rsvr_setup@ + * above) of an operation has been completed. + * + * If the first stage is complete, then this shifts stuff about + * in the reservoir and prepares for the second stage; if the + * second stage is complete, then it copies the remaining input + * into the reservoir and marks the state as complete. + */ + +int rsvr_done(rsvr_state *st) +{ + assert(!st->sz); + switch (st->src) { + case RSVRSRC_RSVR: + if (st->plan.from_rsvr) { + if (st->plan.from_rsvr < *st->used) { + memmove(st->rsvr, st->rsvr + st->plan.from_rsvr, + *st->used - st->plan.from_rsvr); + } + *st->used -= st->plan.from_rsvr; + } + st->src = RSVRSRC_INPUT; + st->p = st->in; st->sz = st->plan.from_input; + return (0); + case RSVRSRC_INPUT: + if (st->plan.tail) { + memcpy(st->rsvr + *st->used, st->p, st->plan.tail); + *st->used += st->plan.tail; + } + st->src = RSVRSRC_DONE; + st->p = 0; st->sz = 0; + return (1); + default: + abort(); + } +} + +/*----- Testing -----------------------------------------------------------*/ + +#ifdef TEST_RIG + +#include +#include +#include + +#include +#include +#include +#include +#include + +struct rng { + uint32 x; +}; + +static void init_rng(struct rng *r) + { r->x = 0; } + +static void step_rng(struct rng *r) + { r->x = U32(0x0d83c207*r->x + 0x380fcfea); } + +DA_DECL(uint_v, unsigned); + +struct testinfo { + rsvr_policy pol; + uint_v chunksz; + uint_v blksz; + unsigned used; + size_t off; + int ok; +}; + +static void show_uint_v(const char *what, const uint_v *v) +{ + size_t i; + + printf("\t%s:", what); + for (i = 0; i < DA_LEN(v); i++) printf("%s%u", i ? ", " : " ", DA(v)[i]); + printf("\n"); +} + +static void report_policy(const struct rsvr_policy *pol) +{ + printf("\tpolicy: flags = 0x%08x%s; blksz = %u; rsvrsz = %u\n", + pol->f, pol->f&RSVRF_FULL ? " full" : pol->f ? "" : " nil", + pol->blksz, pol->rsvrsz); +} + +static void report_testinfo(const struct testinfo *info) +{ + report_policy(&info->pol); + show_uint_v("chunksz", &info->chunksz); + show_uint_v("blksz", &info->blksz); + printf("\treservoir level = %u\n", info->used); + printf("\toffset = %lu\n", (unsigned long)info->off); +} + +static void check(struct rng *r, struct testinfo *info, + const void *p, size_t sz) +{ + const octet *q = p; + unsigned x; + + while (sz) { + x = U8(r->x); + if (info->ok && *q != x) { + printf("\n*** FAIL data mismatch (0x%02x /= 0x%02x)\n", *q, x); + report_testinfo(info); + info->ok = 0; + } + q++; sz--; info->off++; + step_rng(r); + } +} + +static void parse_intlist(uint_v *v, const char *p) +{ + char *q; + unsigned long n; + int e = errno; + + for (;;) { + while (isspace((unsigned char)*p)) p++; + if (!*p) break; + if (*p == ',') p++; + while (isspace((unsigned char)*p)) p++; + errno = 0; n = strtoul(p, &q, 0); + if (errno || (*q && *q != ',' && !isspace((unsigned char)*q))) + die(1, "invalid int list"); + p = q; DA_PUSH(v, n); + } + errno = e; +} + +int vrfy_plan(dstr *dv) +{ + rsvr_policy pol; + rsvr_plan want, calc; + unsigned used; + size_t insz; + int ok = 1; + + pol.f = *(unsigned long *)dv[0].buf; + pol.blksz = *(unsigned long *)dv[1].buf; + pol.rsvrsz = *(unsigned long *)dv[2].buf; + used = *(unsigned long *)dv[3].buf; + insz = *(unsigned long *)dv[4].buf; + want.head = *(unsigned long *)dv[5].buf; + want.from_rsvr = *(unsigned long *)dv[6].buf; + want.from_input = *(unsigned long *)dv[7].buf; + want.tail = *(unsigned long *)dv[8].buf; + + rsvr_mkplan(&calc, &pol, used, insz); + + if (want.head != calc.head || + want.from_rsvr != calc.from_rsvr || + want.from_input != calc.from_input || + want.tail != calc.tail) { + printf("\n*** FAIL plan doesn't match\n"); + report_policy(&pol); + printf("\treservoir level = %u\n", used); + printf("\tinput size = %lu\n", (unsigned long)insz); +#define SHOW(what, slot) do { \ + printf("\t" what " (calc) %lu %s %lu (want)\n", \ + (unsigned long)calc.slot, \ + calc.slot == want.slot ? "=" : "/=", \ + (unsigned long)want.slot); \ +} while(0) + SHOW("head", head); + SHOW("from reservoir", from_rsvr); + SHOW("from input", from_input); + SHOW("tail", tail); +#undef SHOW + ok = 0; + } + + return (ok); +} + +static int vrfy_copy(dstr *dv) +{ + struct testinfo info; + rsvr_state st; + struct rng ra, rb; + octet *buf = 0, *rsvr; + const void *p; + size_t i, j, bsz = 0; + unsigned n, used0, lb, ub, fin; + + init_rng(&ra); init_rng(&rb); + info.pol.f = *(unsigned long *)dv[0].buf; + info.pol.blksz = *(unsigned long *)dv[1].buf; + info.pol.rsvrsz = *(unsigned long *)dv[2].buf; + info.ok = 1; info.used = 0; info.off = 0; + rsvr = xmalloc(info.pol.rsvrsz); + DA_CREATE(&info.chunksz); parse_intlist(&info.chunksz, dv[3].buf); + DA_CREATE(&info.blksz); parse_intlist(&info.blksz, dv[4].buf); + for (i = 0; i < DA_LEN(&info.chunksz); i++) + if (bsz < DA(&info.chunksz)[i]) bsz = DA(&info.chunksz)[i]; + buf = xmalloc(bsz); + for (i = 0; i < DA_LEN(&info.chunksz); i++) { + n = DA(&info.chunksz)[i]; + for (j = 0; j < n; j++) { buf[j] = U8(ra.x); step_rng(&ra); } + used0 = info.used; + rsvr_setup(&st, &info.pol, rsvr, &info.used, buf, n); + if (n != st.plan.head + st.plan.from_input + st.plan.tail) { + printf("\n*** FAIL input size crosscheck " + "(%u /= %u + %lu + %u = %lu)\n", + n, + st.plan.head, (unsigned long)st.plan.from_input, st.plan.tail, + (unsigned long)(st.plan.head + + st.plan.from_input + + st.plan.tail)); + report_testinfo(&info); + info.ok = 0; + } + if (st.plan.from_rsvr%info.pol.blksz) { + printf("\n*** FAIL reservoir chunk %u misaligned\n", + st.plan.from_rsvr); + report_testinfo(&info); + info.ok = 0; + } + if (st.plan.from_input%info.pol.blksz) { + printf("\n*** FAIL direct chunk %lu misaligned\n", + (unsigned long)st.plan.from_input); + report_testinfo(&info); + info.ok = 0; + } + if (st.plan.head > info.pol.rsvrsz - used0) { + printf("\n*** FAIL top-up out of range (%u + %u = %u > %u)\n", + used0, st.plan.head, used0 + st.plan.head, info.pol.rsvrsz); + report_testinfo(&info); + info.ok = 0; + } + if (st.plan.from_rsvr > used0 + st.plan.head) { + printf("\n*** FAIL shift out of range (%u > %u + %u = %u)\n", + st.plan.from_rsvr, + used0, st.plan.head, used0 + st.plan.head); + report_testinfo(&info); + info.ok = 0; + } + if (st.plan.head != n) { + ub = info.pol.rsvrsz + !!(info.pol.f&RSVRF_FULL); + lb = ub - info.pol.blksz; + fin = used0 + st.plan.head - st.plan.from_rsvr + st.plan.tail; + if (lb > fin) { + printf("\n*** FAIL final level out of bounds " + "(%u > %u = %u + %u - %u + %u)\n", + lb, fin, + used0, st.plan.head, st.plan.from_rsvr, st.plan.tail); + report_testinfo(&info); + info.ok = 0; + } + if (fin >= ub) { + printf("\n*** FAIL final level out of bounds " + "(%u + %u - %u + %u = %u >= %u)\n", + used0, st.plan.head, st.plan.from_rsvr, st.plan.tail, + fin, ub); + report_testinfo(&info); + info.ok = 0; + } + } + + if (!info.ok) break; + RSVR_DO(&st) { + for (j = 0; j < DA_LEN(&info.blksz); j++) { + n = DA(&info.blksz)[j]; + while ((p = RSVR_NEXT(&st, n)) != 0) check(&rb, &info, p, n); + } + } + } + + DA_DESTROY(&info.chunksz); + DA_DESTROY(&info.blksz); + xfree(rsvr); xfree(buf); + return (info.ok); +} + +static const struct test_chunk tests[] = { + { "plan", vrfy_plan, + { &type_ulong, &type_ulong, &type_ulong, &type_ulong, &type_ulong, + &type_ulong, &type_ulong, &type_ulong, &type_ulong } }, + { "copy", vrfy_copy, + { &type_ulong, &type_ulong, &type_ulong, &type_string, &type_string } }, + { 0, 0, { 0 } } +}; + +int main(int argc, char *argv[]) +{ + test_run(argc, argv, tests, SRCDIR "/t/rsvr"); + return (0); +} + +#endif + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/base/rsvr.h b/base/rsvr.h new file mode 100644 index 00000000..9fb9c0a6 --- /dev/null +++ b/base/rsvr.h @@ -0,0 +1,195 @@ +/* -*-c-*- + * + * Reservoir and buffer handling + * + * (c) 2017 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef CATACOMB_RSVR_H +#define CATACOMB_RSVR_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +/*----- Data structures ---------------------------------------------------*/ + +typedef struct rsvr_policy { + unsigned f; /* Flags... */ +#define RSVRF_FULL 1u /* Hold back a full reservoir */ + unsigned blksz; /* Block size */ + unsigned rsvrsz; /* Reservoir size; multiple of + * @blksz@ */ +} rsvr_policy; + +typedef struct rsvr_plan { + unsigned head; /* First, accumulate @head@ bytes + * into the reservoir */ + unsigned from_rsvr; /* Next, process @from_rsvr@ bytes + * from the reservoir */ + size_t from_input; /* Then, process @from_input@ bytes + * directly from the input */ + unsigned tail; /* Finally, accumulate the remaining + * @tail@ bytes of input into the + * reservoir */ +} rsvr_plan; + +enum { RSVRSRC_RSVR, RSVRSRC_INPUT, RSVRSRC_DONE }; + +typedef struct rsvr_state { + rsvr_plan plan; + unsigned *used; + unsigned char *rsvr; + const unsigned char *in, *p; + size_t sz; + unsigned src; +} rsvr_state; + +/*----- Functions provided ------------------------------------------------*/ + +/* --- @rsvr_mkplan@ --- * + * + * Arguments: @rsvr_plan *plan@ = pointer to plan to fill in + * @const rsvr_policy *pol@ = reservoir policy to follow + * @size_t used@ = amount of data in the reservoir + * @size_t insz@ = amount of fresh input data arriving + * + * Returns: --- + * + * Use: Prepares a plan for feeding input data into a block-oriented + * operation. + * + * The caller's code for following the plan proceeds in four + * parts. + * + * 1. Insert the first @plan->head@ input items into the + * reservoir; there will be sufficient space, and + * @plan->head@ will be at most @pol->blksz@. + * + * 2. Process the first @plan->from_rsvr@ items from the + * reservoir, shifting the remaining items forward; + * @plan->from_rsvr@ will be a multiple of @pol->blksz@. + * + * 3. Process the next @plan->from_input@ items directly from + * the input; @plan->from_input@ will be a multiple of + * @pol->blksz@. + * + * 4. Insert the remaining @plan->tail@ input items into the + * reservoir for next time. + */ + +extern void rsvr_mkplan(rsvr_plan */*plan*/, const rsvr_policy */*pol*/, + size_t /*used*/, size_t /*insz*/); + +/* --- @rsvr_setup@ --- * + * + * Arguments: @rsvr_state *st@ = pointer to state structure to fill in + * @const rsvr_policy *pol@ = reservoir policy to follow + * @void *rsvr@ = pointer to the actual reservoir + * @unsigned *used@ = pointer to the reservoir level + * @const void *in@ = pointer to the input data + * @size_t insz@ = size of the input + * + * Returns: --- + * + * Use: Prepares for a simple operation. This performs the initial + * copy of input data into the reservoir, and prepares for the + * next step. + * + * After this, the calling code should usually proceed as + * follows. + * + * 1. Call @RSVR_NEXT@ in a sequence of loops, with + * successively smaller values of @n@, to process waiting + * data from the reservoir. Usually, each @n@ will be some + * multiple of the block size @pol->blksz@, and the final + * loop will have @n = pol->blksz@. + * + * 2. Call @rsvr_done@ to indicate that this has been done. + * + * 3. Call @RSVR_NEXT@ in a sequence of loops, as in step 1, + * to process the remaining data from the input buffer. + * + * 4. Call @rsvr_done@ to indicate that the job is complete. + */ + +extern void rsvr_setup(rsvr_state */*st*/, const rsvr_policy */*pol*/, + void */*rsvr*/, unsigned */*used*/, + const void */*in*/, size_t /*insz*/); + +/* --- @RSVR_NEXT@, @rsvr_next@ --- * + * + * Arguments: @rsvr_state *st@ = pointer to the state structure + * @size_t n@ = amount of input data required, in bytes; should + * usually be a multiple of @pol->blksz@ + * + * Returns: A pointer to the next @n@ bytes of input, or null if there is + * insufficient data remaining. + */ + +#define RSVR_NEXT(st, n) \ + ((n) > (st)->sz \ + ? 0 \ + : ((st)->sz -= (n), \ + (st)->p += (n), \ + (const void *)((st)->p - (n)))) +extern const void *rsvr_next(rsvr_state */*st*/, size_t /*n*/); + +/* --- @rsvr_done@ --- * + * + * Arguments: @rsvr_state *st@ = pointer to the state structure + * + * Returns: Zero after the first pass, nonzero after the second. + * + * Use: Reports that the first or second stage (see @rsvr_setup@ + * above) of an operation has been completed. + * + * If the first stage is complete, then this shifts stuff about + * in the reservoir and prepares for the second stage; if the + * second stage is complete, then it copies the remaining input + * into the reservoir and marks the state as complete. + */ + +extern int rsvr_done(rsvr_state */*st*/); + +/* --- @RSVR_DO@ --- * + * + * Arguments: @st@ = pointer to state structure + * + * Use: Invoke as @RSVR_DO(st) stmt@: performs two passes of @stmt@ + * over the reservoir and input buffers respectively. + */ + +#define RSVR_DO(st) switch (0) while (!rsvr_done(st)) case 0: + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/base/t/rsvr b/base/t/rsvr new file mode 100644 index 00000000..188adb38 --- /dev/null +++ b/base/t/rsvr @@ -0,0 +1,26 @@ +### -*-conf-*- +### Tests for reservoir management. + +plan { + ## F BLKSZ RSVRSZ USED INSZ HEAD FROM-RSVR FROM-INPUT TAIL + 0 8 8 0 0 0 0 0 0; + 0 8 8 0 1 1 0 0 0; + 0 8 8 7 1 1 8 0 0; + 1 8 8 7 1 1 0 0 0; + 0 8 8 0 16 0 0 16 0; + 0 8 8 1 15 7 8 8 0; + 1 8 8 1 15 7 8 0 8; + 0 8 8 1 16 7 8 8 1; + 1 8 8 1 16 7 8 8 1; + + 0 8 8 0 1 1 0 0 0; + 0 8 8 1 4 4 0 0 0; + 0 8 8 5 7 3 8 0 4; + 0 8 8 4 31 4 8 24 3; + 0 8 8 3 5 5 8 0 0; +} + +copy { + ## F BLKSZ RSVRSZ CHUNKSZ,... BLKSZ,... + 0 8 8 1,4,7,31,5 16,8; +} diff --git a/base/test-regdump-a64.S b/base/test-regdump-a64.S new file mode 100644 index 00000000..f91331e4 --- /dev/null +++ b/base/test-regdump-a64.S @@ -0,0 +1,27 @@ +#include "config.h" +#include "asm-common.h" +#include "regdump.h" + + .text + + .p2align 5 +vec: + .long 1, 2, 3, 4, 5, 6, 7, 8 + +FUNC(main) + + pushreg x29, x30 + setfp + endprologue + + bl regdump_init + + cmp x0, x0 + reg "simd", v1 + + mov w0, #0 + dropfp + popreg x29, x30 + ret + +ENDFUNC diff --git a/base/test-regdump-arm.S b/base/test-regdump-arm.S new file mode 100644 index 00000000..a49b101c --- /dev/null +++ b/base/test-regdump-arm.S @@ -0,0 +1,33 @@ +#include "config.h" +#include "asm-common.h" +#include "regdump.h" + + .text + .arch armv7-a + + .p2align 5 +vec: + .long 1, 2, 3, 4, 5, 6, 7, 8 + +FUNC(main) + + pushreg r11, r14 + setfp + endprologue + + bl regdump_init + + cmp r0, r0 + regdump gp=t + reg "general purpose", r1 + reg " flags", cpsr + reg " simd", q0, fmt=REGF_HEX | REGF_32 | REGF_16 + reg " float", d0, fmt=REGF_FLT | REGF_64 + reg " float", s0 + reg " float status", fpscr + + mov r0, #0 + dropfp + popreg r11, pc + +ENDFUNC diff --git a/base/test-regdump-x86ish.S b/base/test-regdump-x86ish.S new file mode 100644 index 00000000..a8c8d435 --- /dev/null +++ b/base/test-regdump-x86ish.S @@ -0,0 +1,38 @@ +#include "config.h" +#include "asm-common.h" +#include "regdump.h" + + .text + + .p2align 5 +vec: + .long 1, 2, 3, 4, 5, 6, 7, 8 + +FUNC(main) + + pushreg R_bp(r) + setfp + and R_sp(r), ~15 + endprologue + + fldz + fld1 + fldpi + fldl2t + fldl2e + fldlg2 + fldln2 + //fld1 + + ldgot + movdqa xmm2, [INTADDR(vec)] + //vmovdqa ymm2, [INTADDR(vec)] + + reg "my fp", xmm2, REGF_FLT | REGF_64 | REGF_32 + + xor eax, eax + dropfp + popreg R_bp(r) + ret + +ENDFUNC diff --git a/configure.ac b/configure.ac index f8ad8b77..b6c40ba5 100644 --- a/configure.ac +++ b/configure.ac @@ -145,7 +145,7 @@ m4_define([catacomb_DEFINE_CPU_OR_ABI], ;;m4_define([catacomb_seen_$3/$$2], [t])])]) catacomb_CPU_FAMILIES([_def]) nil) ;; - *) AC_MSG_ERROR([BUG: unexpected $1 \`$1']) ;; + *) AC_MSG_ERROR([BUG: unexpected $1 \`$$1']) ;; esac]) dnl Now that's out the way, we can explain what we're doing. @@ -179,6 +179,26 @@ case $CPUFAM in *) AC_MSG_RESULT([$CPUFAM/$ABI]) ;; esac +dnl Consider enabling support for assembler-level debugging toys. +AC_ARG_ENABLE([asm-debug], + AS_HELP_STRING([--enable-asm-debug], + [enable assembler debugging features]), + [mdw_asm_debug=$enableval], [mdw_asm_debug=no]) +case $CPUFAM in nil) mdw_asm_debug=no ;; esac +case $mdw_asm_debug in + no) ;; + *) AC_DEFINE([ENABLE_ASM_DEBUG], [1], + [Define to enable assembler-level debugging.]) ;; +esac +AM_CONDITIONAL([ASM_DEBUG], [test x$mdw_asm_debug != xno]) + +dnl Check for leading underscores on C symbols. +LT_SYS_SYMBOL_USCORE +case $sys_symbol_underscore in + yes) AC_DEFINE([SYM_USCORE], [1], + [Define if C symbols are prefixed with an underscore.]) ;; +esac + dnl-------------------------------------------------------------------------- dnl CPU-specific assembler features. @@ -278,6 +298,9 @@ AC_CHECK_HEADERS([sys/auxv.h]) AC_CHECK_HEADERS([linux/auxvec.h]) AC_CHECK_FUNCS([getauxval]) +dnl Some equipment for measuring CPU performance. +AC_CHECK_HEADERS([linux/perf_event.h]) + dnl Find the bit lengths of the obvious integer types. This will be useful dnl when deciding on a representation for multiprecision integers. type_bits="" type_bits_sep="" @@ -400,7 +423,7 @@ dnl Set the master libraries we need. AC_SUBST([CATACOMB_LIBS]) dnl Necessary support libraries. -PKG_CHECK_MODULES([mLib], [mLib >= 2.2.2.1]) +PKG_CHECK_MODULES([mLib], [mLib >= 2.3.0]) AM_CFLAGS="$AM_CFLAGS $mLib_CFLAGS" dnl-------------------------------------------------------------------------- diff --git a/debian/catacomb2.symbols b/debian/catacomb2.symbols index 9b82e2ac..36f4a565 100644 --- a/debian/catacomb2.symbols +++ b/debian/catacomb2.symbols @@ -23,9 +23,25 @@ libcatacomb.so.2 catacomb2 #MINVER# ## dispatch cpu_feature_p@Base 2.2.3 dispatch_debug@Base 2.2.3 + (optional|arch=i386 amd64)dispatch_x86ish_cpuid@Base 2.5.0 + (optional|arch=i386 amd64)dispatch_x86ish_xmmregisters_p@Base 2.5.0 + +## regdump (available with `--enable-asm-debug') + (optional)regdump_init@Base 2.5.0 + (optional)regdump@Base 2.5.0 + (optional)regdump_freshline@Base 2.5.0 + (optional)regdump_gp@Base 2.5.0 + (optional)regdump_fp@Base 2.5.0 + (optional)regdump_simd@Base 2.5.0 + (optional)regdump_gprstr@Base 2.5.0 + (optional)regdump_gpsave@Base 2.5.0 + (optional)regdump_xtrstr@Base 2.5.0 + (optional)regdump_xtsave@Base 2.5.0 + (optional|arch=armel armhf)regdump__flags@Base 2.5.0 ## keysz keysz@Base 2.1.0 + keysz_pad@Base 2.5.0 keysz_fromdl@Base 2.1.1 keysz_fromec@Base 2.1.1 keysz_fromif@Base 2.1.1 @@ -43,6 +59,12 @@ libcatacomb.so.2 catacomb2 #MINVER# l_free@Base 2.1.0 l_purge@Base 2.1.0 +## rsvr + rsvr_setup@Base 2.5.0 + rsvr_mkplan@Base 2.5.0 + rsvr_next@Base 2.5.0 + rsvr_done@Base 2.5.0 + ###-------------------------------------------------------------------------- ### Mathematical infrastructure. @@ -102,11 +124,17 @@ libcatacomb.so.2 catacomb2 #MINVER# mpx_kmul@Base 2.1.1 mpx_ksqr@Base 2.1.1 (optional|arch=i386)mpx_umul4_x86_sse2@Base 2.3.0 + (optional|arch=i386)mpx_umul4_x86_avx@Base 2.3.0 (optional|arch=amd64)mpx_umul4_amd64_sse2@Base 2.3.0 + (optional|arch=amd64)mpx_umul4_amd64_avx@Base 2.3.0 (optional|arch=i386)mpxmont_mul4_x86_sse2@Base 2.3.0 + (optional|arch=i386)mpxmont_mul4_x86_avx@Base 2.3.0 (optional|arch=amd64)mpxmont_mul4_amd64_sse2@Base 2.3.0 + (optional|arch=amd64)mpxmont_mul4_amd64_avx@Base 2.3.0 (optional|arch=i386)mpxmont_redc4_x86_sse2@Base 2.3.0 + (optional|arch=i386)mpxmont_redc4_x86_avx@Base 2.3.0 (optional|arch=amd64)mpxmont_redc4_amd64_sse2@Base 2.3.0 + (optional|arch=amd64)mpxmont_redc4_amd64_avx@Base 2.3.0 ## mparena mparena_create@Base 2.0.0 @@ -363,7 +391,8 @@ libcatacomb.so.2 catacomb2 #MINVER# pgen_filter@Base 2.1.1 pgen_test@Base 2.1.1 pgen_jump@Base 2.2.4 - pgen_primep@Base 2.1.1 + pgen_granfrob@Base 2.5.0 + pgen_primep@Base 2.5.0 pgen_gcdstep@Base 2.1.1 pgen_simulstep@Base 2.1.1 pgen_simultest@Base 2.1.1 @@ -616,6 +645,7 @@ libcatacomb.so.2 catacomb2 #MINVER# rand_noisesrc@Base 2.2.3 rand_seed@Base 2.2.3 rand_quick@Base 2.2.3 + (optional|arch=i386 amd64)rand_quick_x86ish_rdrand@Base 2.5.0 rand_key@Base 2.2.3 rand_add@Base 2.2.3 rand_goodbits@Base 2.2.3 @@ -669,6 +699,12 @@ libcatacomb.so.2 catacomb2 #MINVER# gcipher_byname@Base 2.1.1 gciphertab@Base 2.1.1 +## gaead + gaead_byname@Base 2.5.0 + gaead_encrypt@Base 2.5.0 + gaead_decrypt@Base 2.5.0 + gaeadtab@Base 2.5.0 + ## ghash ghash_byname@Base 2.1.1 ghashtab@Base 2.1.1 @@ -677,6 +713,78 @@ libcatacomb.so.2 catacomb2 #MINVER# gmac_byname@Base 2.1.1 gmactab@Base 2.1.1 +## ccm + ccm_check@Base 2.5.0 + ccm_fmtctr@Base 2.5.0 + ccm_fmthdr@Base 2.5.0 + +## gcm + gcm_mktable@Base 2.5.0 + gcm_ghashdone@Base 2.5.0 + gcm_concat@Base 2.5.0 + gcm_mulk_64b@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_64b_x86ish_pclmul@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_64b_x86ish_pclmul_avx@Base 2.5.0 + (optional|arch=armel armhf)gcm_mulk_64b_arm_crypto@Base 2.5.0 + (optional|arch=arm64)gcm_mulk_64b_arm64_pmull@Base 2.5.0 + gcm_mulk_64l@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_64l_x86ish_pclmul@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_64l_x86ish_pclmul_avx@Base 2.5.0 + (optional|arch=armel armhf)gcm_mulk_64l_arm_crypto@Base 2.5.0 + (optional|arch=arm64)gcm_mulk_64l_arm64_pmull@Base 2.5.0 + gcm_mulk_96b@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_96b_x86ish_pclmul@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_96b_x86ish_pclmul_avx@Base 2.5.0 + (optional|arch=armel armhf)gcm_mulk_96b_arm_crypto@Base 2.5.0 + (optional|arch=arm64)gcm_mulk_96b_arm64_pmull@Base 2.5.0 + gcm_mulk_96l@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_96l_x86ish_pclmul@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_96l_x86ish_pclmul_avx@Base 2.5.0 + (optional|arch=armel armhf)gcm_mulk_96l_arm_crypto@Base 2.5.0 + (optional|arch=arm64)gcm_mulk_96l_arm64_pmull@Base 2.5.0 + gcm_mulk_128b@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_128b_x86ish_pclmul@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_128b_x86ish_pclmul_avx@Base 2.5.0 + (optional|arch=armel armhf)gcm_mulk_128b_arm_crypto@Base 2.5.0 + (optional|arch=arm64)gcm_mulk_128b_arm64_pmull@Base 2.5.0 + gcm_mulk_128l@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_128l_x86ish_pclmul@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_128l_x86ish_pclmul_avx@Base 2.5.0 + (optional|arch=armel armhf)gcm_mulk_128l_arm_crypto@Base 2.5.0 + (optional|arch=arm64)gcm_mulk_128l_arm64_pmull@Base 2.5.0 + gcm_mulk_192b@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_192b_x86ish_pclmul@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_192b_x86ish_pclmul_avx@Base 2.5.0 + (optional|arch=armel armhf)gcm_mulk_192b_arm_crypto@Base 2.5.0 + (optional|arch=arm64)gcm_mulk_192b_arm64_pmull@Base 2.5.0 + gcm_mulk_192l@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_192l_x86ish_pclmul@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_192l_x86ish_pclmul_avx@Base 2.5.0 + (optional|arch=armel armhf)gcm_mulk_192l_arm_crypto@Base 2.5.0 + (optional|arch=arm64)gcm_mulk_192l_arm64_pmull@Base 2.5.0 + gcm_mulk_256b@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_256b_x86ish_pclmul@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_256b_x86ish_pclmul_avx@Base 2.5.0 + (optional|arch=armel armhf)gcm_mulk_256b_arm_crypto@Base 2.5.0 + (optional|arch=arm64)gcm_mulk_256b_arm64_pmull@Base 2.5.0 + gcm_mulk_256l@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_256l_x86ish_pclmul@Base 2.5.0 + (optional|arch=i386 amd64)gcm_mulk_256l_x86ish_pclmul_avx@Base 2.5.0 + (optional|arch=armel armhf)gcm_mulk_256l_arm_crypto@Base 2.5.0 + (optional|arch=arm64)gcm_mulk_256l_arm64_pmull@Base 2.5.0 + +## latinpoly + latinpoly_noncesz@Base 2.5.0 + latinpoly_tagsz@Base 2.5.0 + latinpoly_aadhash_naclbox@Base 2.5.0 + latinpoly_aadhash_poly1305@Base 2.5.0 + latinpoly_aaddestroy@Base 2.5.0 + latinpoly_tag@Base 2.5.0 + +## ocb + ocb_ctz@Base 2.5.0 + ocb_ctzl@Base 2.5.0 + ## blowfish blowfish_init@Base 2.0.0 blowfish_keysz@Base 2.0.0 @@ -719,6 +827,80 @@ libcatacomb.so.2 catacomb2 #MINVER# blowfish_counterbdry@Base 2.0.0 blowfish_counter@Base 2.0.0 blowfish_counterrand@Base 2.0.0 + blowfish_ccminit@Base 2.5.0 + blowfish_ccmreinit@Base 2.5.0 + blowfish_ccmnoncesz@Base 2.5.0 + blowfish_ccmtagsz@Base 2.5.0 + blowfish_ccmaadhash@Base 2.5.0 + blowfish_ccmencrypt@Base 2.5.0 + blowfish_ccmdecrypt@Base 2.5.0 + blowfish_ccmencryptdone@Base 2.5.0 + blowfish_ccmdecryptdone@Base 2.5.0 + blowfish_ccm@Base 2.5.0 + blowfish_eaxinit@Base 2.5.0 + blowfish_eaxreinit@Base 2.5.0 + blowfish_eaxsetkey@Base 2.5.0 + blowfish_eaxnoncesz@Base 2.5.0 + blowfish_eaxtagsz@Base 2.5.0 + blowfish_eaxaadinit@Base 2.5.0 + blowfish_eaxaadhash@Base 2.5.0 + blowfish_eaxencrypt@Base 2.5.0 + blowfish_eaxdecrypt@Base 2.5.0 + blowfish_eaxencryptdone@Base 2.5.0 + blowfish_eaxdecryptdone@Base 2.5.0 + blowfish_eax@Base 2.5.0 + blowfish_gcminit@Base 2.5.0 + blowfish_gcmreinit@Base 2.5.0 + blowfish_gcmsetkey@Base 2.5.0 + blowfish_gcmnoncesz@Base 2.5.0 + blowfish_gcmtagsz@Base 2.5.0 + blowfish_gcmaadinit@Base 2.5.0 + blowfish_gcmaadhash@Base 2.5.0 + blowfish_gcmencrypt@Base 2.5.0 + blowfish_gcmdecrypt@Base 2.5.0 + blowfish_gcmencryptdone@Base 2.5.0 + blowfish_gcmdecryptdone@Base 2.5.0 + blowfish_gcm@Base 2.5.0 + blowfish_ocb1init@Base 2.5.0 + blowfish_ocb1reinit@Base 2.5.0 + blowfish_ocb1setkey@Base 2.5.0 + blowfish_ocb1policy@Base 2.5.0 + blowfish_ocb1noncesz@Base 2.5.0 + blowfish_ocb1tagsz@Base 2.5.0 + blowfish_ocb1aadinit@Base 2.5.0 + blowfish_ocb1aadhash@Base 2.5.0 + blowfish_ocb1aadtag@Base 2.5.0 + blowfish_ocb1encrypt@Base 2.5.0 + blowfish_ocb1decrypt@Base 2.5.0 + blowfish_ocb1encryptdone@Base 2.5.0 + blowfish_ocb1decryptdone@Base 2.5.0 + blowfish_ocb1@Base 2.5.0 + blowfish_ocb3init@Base 2.5.0 + blowfish_ocb3step@Base 2.5.0 + blowfish_ocb3reinit@Base 2.5.0 + blowfish_ocb3setkey@Base 2.5.0 + blowfish_ocb3noncesz@Base 2.5.0 + blowfish_ocb3aadinit@Base 2.5.0 + blowfish_ocb3aadhash@Base 2.5.0 + blowfish_ocb3encrypt@Base 2.5.0 + blowfish_ocb3decrypt@Base 2.5.0 + blowfish_ocb3encryptdone@Base 2.5.0 + blowfish_ocb3decryptdone@Base 2.5.0 + blowfish_ocb3tagsz@Base 2.5.0 + blowfish_ocb3@Base 2.5.0 + blowfish_omacmasks@Base 2.5.0 + blowfish_omacpolicy@Base 2.5.0 + blowfish_omacdone@Base 2.5.0 + blowfish_cmacinit@Base 2.5.0 + blowfish_cmacsetkey@Base 2.5.0 + blowfish_cmachash@Base 2.5.0 + blowfish_cmacdone@Base 2.5.0 + blowfish_cmac@Base 2.5.0 + blowfish_pmac1init@Base 2.5.0 + blowfish_pmac1setkey@Base 2.5.0 + blowfish_pmac1hash@Base 2.5.0 + blowfish_pmac1done@Base 2.5.0 + blowfish_pmac1@Base 2.5.0 ## cast128 cast128_init@Base 2.0.0 @@ -763,6 +945,80 @@ libcatacomb.so.2 catacomb2 #MINVER# cast128_counterbdry@Base 2.0.0 cast128_counter@Base 2.0.0 cast128_counterrand@Base 2.0.0 + cast128_ccminit@Base 2.5.0 + cast128_ccmreinit@Base 2.5.0 + cast128_ccmnoncesz@Base 2.5.0 + cast128_ccmtagsz@Base 2.5.0 + cast128_ccmaadhash@Base 2.5.0 + cast128_ccmencrypt@Base 2.5.0 + cast128_ccmdecrypt@Base 2.5.0 + cast128_ccmencryptdone@Base 2.5.0 + cast128_ccmdecryptdone@Base 2.5.0 + cast128_ccm@Base 2.5.0 + cast128_eaxinit@Base 2.5.0 + cast128_eaxreinit@Base 2.5.0 + cast128_eaxsetkey@Base 2.5.0 + cast128_eaxnoncesz@Base 2.5.0 + cast128_eaxtagsz@Base 2.5.0 + cast128_eaxaadinit@Base 2.5.0 + cast128_eaxaadhash@Base 2.5.0 + cast128_eaxencrypt@Base 2.5.0 + cast128_eaxdecrypt@Base 2.5.0 + cast128_eaxencryptdone@Base 2.5.0 + cast128_eaxdecryptdone@Base 2.5.0 + cast128_eax@Base 2.5.0 + cast128_gcminit@Base 2.5.0 + cast128_gcmreinit@Base 2.5.0 + cast128_gcmsetkey@Base 2.5.0 + cast128_gcmnoncesz@Base 2.5.0 + cast128_gcmtagsz@Base 2.5.0 + cast128_gcmaadinit@Base 2.5.0 + cast128_gcmaadhash@Base 2.5.0 + cast128_gcmencrypt@Base 2.5.0 + cast128_gcmdecrypt@Base 2.5.0 + cast128_gcmencryptdone@Base 2.5.0 + cast128_gcmdecryptdone@Base 2.5.0 + cast128_gcm@Base 2.5.0 + cast128_ocb1init@Base 2.5.0 + cast128_ocb1reinit@Base 2.5.0 + cast128_ocb1setkey@Base 2.5.0 + cast128_ocb1policy@Base 2.5.0 + cast128_ocb1noncesz@Base 2.5.0 + cast128_ocb1tagsz@Base 2.5.0 + cast128_ocb1aadinit@Base 2.5.0 + cast128_ocb1aadhash@Base 2.5.0 + cast128_ocb1aadtag@Base 2.5.0 + cast128_ocb1encrypt@Base 2.5.0 + cast128_ocb1decrypt@Base 2.5.0 + cast128_ocb1encryptdone@Base 2.5.0 + cast128_ocb1decryptdone@Base 2.5.0 + cast128_ocb1@Base 2.5.0 + cast128_ocb3init@Base 2.5.0 + cast128_ocb3step@Base 2.5.0 + cast128_ocb3reinit@Base 2.5.0 + cast128_ocb3setkey@Base 2.5.0 + cast128_ocb3noncesz@Base 2.5.0 + cast128_ocb3aadinit@Base 2.5.0 + cast128_ocb3aadhash@Base 2.5.0 + cast128_ocb3encrypt@Base 2.5.0 + cast128_ocb3decrypt@Base 2.5.0 + cast128_ocb3encryptdone@Base 2.5.0 + cast128_ocb3decryptdone@Base 2.5.0 + cast128_ocb3tagsz@Base 2.5.0 + cast128_ocb3@Base 2.5.0 + cast128_omacmasks@Base 2.5.0 + cast128_omacpolicy@Base 2.5.0 + cast128_omacdone@Base 2.5.0 + cast128_cmacinit@Base 2.5.0 + cast128_cmacsetkey@Base 2.5.0 + cast128_cmachash@Base 2.5.0 + cast128_cmacdone@Base 2.5.0 + cast128_cmac@Base 2.5.0 + cast128_pmac1init@Base 2.5.0 + cast128_pmac1setkey@Base 2.5.0 + cast128_pmac1hash@Base 2.5.0 + cast128_pmac1done@Base 2.5.0 + cast128_pmac1@Base 2.5.0 ## cast256 cast256_init@Base 2.0.0 @@ -805,6 +1061,80 @@ libcatacomb.so.2 catacomb2 #MINVER# cast256_counterbdry@Base 2.0.0 cast256_counter@Base 2.0.0 cast256_counterrand@Base 2.0.0 + cast256_ccminit@Base 2.5.0 + cast256_ccmreinit@Base 2.5.0 + cast256_ccmnoncesz@Base 2.5.0 + cast256_ccmtagsz@Base 2.5.0 + cast256_ccmaadhash@Base 2.5.0 + cast256_ccmencrypt@Base 2.5.0 + cast256_ccmdecrypt@Base 2.5.0 + cast256_ccmencryptdone@Base 2.5.0 + cast256_ccmdecryptdone@Base 2.5.0 + cast256_ccm@Base 2.5.0 + cast256_eaxinit@Base 2.5.0 + cast256_eaxreinit@Base 2.5.0 + cast256_eaxsetkey@Base 2.5.0 + cast256_eaxnoncesz@Base 2.5.0 + cast256_eaxtagsz@Base 2.5.0 + cast256_eaxaadinit@Base 2.5.0 + cast256_eaxaadhash@Base 2.5.0 + cast256_eaxencrypt@Base 2.5.0 + cast256_eaxdecrypt@Base 2.5.0 + cast256_eaxencryptdone@Base 2.5.0 + cast256_eaxdecryptdone@Base 2.5.0 + cast256_eax@Base 2.5.0 + cast256_gcminit@Base 2.5.0 + cast256_gcmreinit@Base 2.5.0 + cast256_gcmsetkey@Base 2.5.0 + cast256_gcmnoncesz@Base 2.5.0 + cast256_gcmtagsz@Base 2.5.0 + cast256_gcmaadinit@Base 2.5.0 + cast256_gcmaadhash@Base 2.5.0 + cast256_gcmencrypt@Base 2.5.0 + cast256_gcmdecrypt@Base 2.5.0 + cast256_gcmencryptdone@Base 2.5.0 + cast256_gcmdecryptdone@Base 2.5.0 + cast256_gcm@Base 2.5.0 + cast256_ocb1init@Base 2.5.0 + cast256_ocb1reinit@Base 2.5.0 + cast256_ocb1setkey@Base 2.5.0 + cast256_ocb1policy@Base 2.5.0 + cast256_ocb1noncesz@Base 2.5.0 + cast256_ocb1tagsz@Base 2.5.0 + cast256_ocb1aadinit@Base 2.5.0 + cast256_ocb1aadhash@Base 2.5.0 + cast256_ocb1aadtag@Base 2.5.0 + cast256_ocb1encrypt@Base 2.5.0 + cast256_ocb1decrypt@Base 2.5.0 + cast256_ocb1encryptdone@Base 2.5.0 + cast256_ocb1decryptdone@Base 2.5.0 + cast256_ocb1@Base 2.5.0 + cast256_ocb3init@Base 2.5.0 + cast256_ocb3step@Base 2.5.0 + cast256_ocb3reinit@Base 2.5.0 + cast256_ocb3setkey@Base 2.5.0 + cast256_ocb3noncesz@Base 2.5.0 + cast256_ocb3aadinit@Base 2.5.0 + cast256_ocb3aadhash@Base 2.5.0 + cast256_ocb3encrypt@Base 2.5.0 + cast256_ocb3decrypt@Base 2.5.0 + cast256_ocb3encryptdone@Base 2.5.0 + cast256_ocb3decryptdone@Base 2.5.0 + cast256_ocb3tagsz@Base 2.5.0 + cast256_ocb3@Base 2.5.0 + cast256_omacmasks@Base 2.5.0 + cast256_omacpolicy@Base 2.5.0 + cast256_omacdone@Base 2.5.0 + cast256_cmacinit@Base 2.5.0 + cast256_cmacsetkey@Base 2.5.0 + cast256_cmachash@Base 2.5.0 + cast256_cmacdone@Base 2.5.0 + cast256_cmac@Base 2.5.0 + cast256_pmac1init@Base 2.5.0 + cast256_pmac1setkey@Base 2.5.0 + cast256_pmac1hash@Base 2.5.0 + cast256_pmac1done@Base 2.5.0 + cast256_pmac1@Base 2.5.0 ## chacha chacha_init@Base 2.2.0 @@ -821,6 +1151,7 @@ libcatacomb.so.2 catacomb2 #MINVER# chacha12_encrypt@Base 2.2.0 chacha20_encrypt@Base 2.2.0 (optional|arch=i386 amd64)chacha_core_x86ish_sse2@Base 2.3.0 + (optional|arch=i386 amd64)chacha_core_x86ish_avx@Base 2.3.0 (optional|arch=armel armhf)chacha_core_arm_neon@Base 2.3.0 (optional|arch=arm64)chacha_core_arm64@Base 2.4.3 chacha8@Base 2.2.0 @@ -835,6 +1166,12 @@ libcatacomb.so.2 catacomb2 #MINVER# chacha8_ietf_rand@Base 2.4.2 chacha12_ietf_rand@Base 2.4.2 chacha20_ietf_rand@Base 2.4.2 + chacha8_naclbox@Base 2.5.0 + chacha12_naclbox@Base 2.5.0 + chacha20_naclbox@Base 2.5.0 + chacha8_poly1305@Base 2.5.0 + chacha12_poly1305@Base 2.5.0 + chacha20_poly1305@Base 2.5.0 hchacha12_prf@Base 2.2.0 hchacha20_prf@Base 2.2.0 hchacha8_prf@Base 2.2.0 @@ -910,6 +1247,80 @@ libcatacomb.so.2 catacomb2 #MINVER# des_counterbdry@Base 2.0.0 des_counter@Base 2.0.0 des_counterrand@Base 2.0.0 + des_ccminit@Base 2.5.0 + des_ccmreinit@Base 2.5.0 + des_ccmnoncesz@Base 2.5.0 + des_ccmtagsz@Base 2.5.0 + des_ccmaadhash@Base 2.5.0 + des_ccmencrypt@Base 2.5.0 + des_ccmdecrypt@Base 2.5.0 + des_ccmencryptdone@Base 2.5.0 + des_ccmdecryptdone@Base 2.5.0 + des_ccm@Base 2.5.0 + des_eaxinit@Base 2.5.0 + des_eaxreinit@Base 2.5.0 + des_eaxsetkey@Base 2.5.0 + des_eaxnoncesz@Base 2.5.0 + des_eaxtagsz@Base 2.5.0 + des_eaxaadinit@Base 2.5.0 + des_eaxaadhash@Base 2.5.0 + des_eaxencrypt@Base 2.5.0 + des_eaxdecrypt@Base 2.5.0 + des_eaxencryptdone@Base 2.5.0 + des_eaxdecryptdone@Base 2.5.0 + des_eax@Base 2.5.0 + des_gcminit@Base 2.5.0 + des_gcmreinit@Base 2.5.0 + des_gcmsetkey@Base 2.5.0 + des_gcmnoncesz@Base 2.5.0 + des_gcmtagsz@Base 2.5.0 + des_gcmaadinit@Base 2.5.0 + des_gcmaadhash@Base 2.5.0 + des_gcmencrypt@Base 2.5.0 + des_gcmdecrypt@Base 2.5.0 + des_gcmencryptdone@Base 2.5.0 + des_gcmdecryptdone@Base 2.5.0 + des_gcm@Base 2.5.0 + des_ocb1init@Base 2.5.0 + des_ocb1reinit@Base 2.5.0 + des_ocb1setkey@Base 2.5.0 + des_ocb1policy@Base 2.5.0 + des_ocb1noncesz@Base 2.5.0 + des_ocb1tagsz@Base 2.5.0 + des_ocb1aadinit@Base 2.5.0 + des_ocb1aadhash@Base 2.5.0 + des_ocb1aadtag@Base 2.5.0 + des_ocb1encrypt@Base 2.5.0 + des_ocb1decrypt@Base 2.5.0 + des_ocb1encryptdone@Base 2.5.0 + des_ocb1decryptdone@Base 2.5.0 + des_ocb1@Base 2.5.0 + des_ocb3init@Base 2.5.0 + des_ocb3step@Base 2.5.0 + des_ocb3reinit@Base 2.5.0 + des_ocb3setkey@Base 2.5.0 + des_ocb3noncesz@Base 2.5.0 + des_ocb3aadinit@Base 2.5.0 + des_ocb3aadhash@Base 2.5.0 + des_ocb3encrypt@Base 2.5.0 + des_ocb3decrypt@Base 2.5.0 + des_ocb3encryptdone@Base 2.5.0 + des_ocb3decryptdone@Base 2.5.0 + des_ocb3tagsz@Base 2.5.0 + des_ocb3@Base 2.5.0 + des_omacmasks@Base 2.5.0 + des_omacpolicy@Base 2.5.0 + des_omacdone@Base 2.5.0 + des_cmacinit@Base 2.5.0 + des_cmacsetkey@Base 2.5.0 + des_cmachash@Base 2.5.0 + des_cmacdone@Base 2.5.0 + des_cmac@Base 2.5.0 + des_pmac1init@Base 2.5.0 + des_pmac1setkey@Base 2.5.0 + des_pmac1hash@Base 2.5.0 + des_pmac1done@Base 2.5.0 + des_pmac1@Base 2.5.0 ## des3 des3_init@Base 2.0.0 @@ -952,6 +1363,80 @@ libcatacomb.so.2 catacomb2 #MINVER# des3_counterbdry@Base 2.0.0 des3_counter@Base 2.0.0 des3_counterrand@Base 2.0.0 + des3_ccminit@Base 2.5.0 + des3_ccmreinit@Base 2.5.0 + des3_ccmnoncesz@Base 2.5.0 + des3_ccmtagsz@Base 2.5.0 + des3_ccmaadhash@Base 2.5.0 + des3_ccmencrypt@Base 2.5.0 + des3_ccmdecrypt@Base 2.5.0 + des3_ccmencryptdone@Base 2.5.0 + des3_ccmdecryptdone@Base 2.5.0 + des3_ccm@Base 2.5.0 + des3_eaxinit@Base 2.5.0 + des3_eaxreinit@Base 2.5.0 + des3_eaxsetkey@Base 2.5.0 + des3_eaxnoncesz@Base 2.5.0 + des3_eaxtagsz@Base 2.5.0 + des3_eaxaadinit@Base 2.5.0 + des3_eaxaadhash@Base 2.5.0 + des3_eaxencrypt@Base 2.5.0 + des3_eaxdecrypt@Base 2.5.0 + des3_eaxencryptdone@Base 2.5.0 + des3_eaxdecryptdone@Base 2.5.0 + des3_eax@Base 2.5.0 + des3_gcminit@Base 2.5.0 + des3_gcmreinit@Base 2.5.0 + des3_gcmsetkey@Base 2.5.0 + des3_gcmnoncesz@Base 2.5.0 + des3_gcmtagsz@Base 2.5.0 + des3_gcmaadinit@Base 2.5.0 + des3_gcmaadhash@Base 2.5.0 + des3_gcmencrypt@Base 2.5.0 + des3_gcmdecrypt@Base 2.5.0 + des3_gcmencryptdone@Base 2.5.0 + des3_gcmdecryptdone@Base 2.5.0 + des3_gcm@Base 2.5.0 + des3_ocb1init@Base 2.5.0 + des3_ocb1reinit@Base 2.5.0 + des3_ocb1setkey@Base 2.5.0 + des3_ocb1policy@Base 2.5.0 + des3_ocb1noncesz@Base 2.5.0 + des3_ocb1tagsz@Base 2.5.0 + des3_ocb1aadinit@Base 2.5.0 + des3_ocb1aadhash@Base 2.5.0 + des3_ocb1aadtag@Base 2.5.0 + des3_ocb1encrypt@Base 2.5.0 + des3_ocb1decrypt@Base 2.5.0 + des3_ocb1encryptdone@Base 2.5.0 + des3_ocb1decryptdone@Base 2.5.0 + des3_ocb1@Base 2.5.0 + des3_ocb3init@Base 2.5.0 + des3_ocb3step@Base 2.5.0 + des3_ocb3reinit@Base 2.5.0 + des3_ocb3setkey@Base 2.5.0 + des3_ocb3noncesz@Base 2.5.0 + des3_ocb3aadinit@Base 2.5.0 + des3_ocb3aadhash@Base 2.5.0 + des3_ocb3encrypt@Base 2.5.0 + des3_ocb3decrypt@Base 2.5.0 + des3_ocb3encryptdone@Base 2.5.0 + des3_ocb3decryptdone@Base 2.5.0 + des3_ocb3tagsz@Base 2.5.0 + des3_ocb3@Base 2.5.0 + des3_omacmasks@Base 2.5.0 + des3_omacpolicy@Base 2.5.0 + des3_omacdone@Base 2.5.0 + des3_cmacinit@Base 2.5.0 + des3_cmacsetkey@Base 2.5.0 + des3_cmachash@Base 2.5.0 + des3_cmacdone@Base 2.5.0 + des3_cmac@Base 2.5.0 + des3_pmac1init@Base 2.5.0 + des3_pmac1setkey@Base 2.5.0 + des3_pmac1hash@Base 2.5.0 + des3_pmac1done@Base 2.5.0 + des3_pmac1@Base 2.5.0 ## desx desx_init@Base 2.0.0 @@ -994,6 +1479,80 @@ libcatacomb.so.2 catacomb2 #MINVER# desx_counterbdry@Base 2.0.0 desx_counter@Base 2.0.0 desx_counterrand@Base 2.0.0 + desx_ccminit@Base 2.5.0 + desx_ccmreinit@Base 2.5.0 + desx_ccmnoncesz@Base 2.5.0 + desx_ccmtagsz@Base 2.5.0 + desx_ccmaadhash@Base 2.5.0 + desx_ccmencrypt@Base 2.5.0 + desx_ccmdecrypt@Base 2.5.0 + desx_ccmencryptdone@Base 2.5.0 + desx_ccmdecryptdone@Base 2.5.0 + desx_ccm@Base 2.5.0 + desx_eaxinit@Base 2.5.0 + desx_eaxreinit@Base 2.5.0 + desx_eaxsetkey@Base 2.5.0 + desx_eaxnoncesz@Base 2.5.0 + desx_eaxtagsz@Base 2.5.0 + desx_eaxaadinit@Base 2.5.0 + desx_eaxaadhash@Base 2.5.0 + desx_eaxencrypt@Base 2.5.0 + desx_eaxdecrypt@Base 2.5.0 + desx_eaxencryptdone@Base 2.5.0 + desx_eaxdecryptdone@Base 2.5.0 + desx_eax@Base 2.5.0 + desx_gcminit@Base 2.5.0 + desx_gcmreinit@Base 2.5.0 + desx_gcmsetkey@Base 2.5.0 + desx_gcmnoncesz@Base 2.5.0 + desx_gcmtagsz@Base 2.5.0 + desx_gcmaadinit@Base 2.5.0 + desx_gcmaadhash@Base 2.5.0 + desx_gcmencrypt@Base 2.5.0 + desx_gcmdecrypt@Base 2.5.0 + desx_gcmencryptdone@Base 2.5.0 + desx_gcmdecryptdone@Base 2.5.0 + desx_gcm@Base 2.5.0 + desx_ocb1init@Base 2.5.0 + desx_ocb1reinit@Base 2.5.0 + desx_ocb1setkey@Base 2.5.0 + desx_ocb1policy@Base 2.5.0 + desx_ocb1noncesz@Base 2.5.0 + desx_ocb1tagsz@Base 2.5.0 + desx_ocb1aadinit@Base 2.5.0 + desx_ocb1aadhash@Base 2.5.0 + desx_ocb1aadtag@Base 2.5.0 + desx_ocb1encrypt@Base 2.5.0 + desx_ocb1decrypt@Base 2.5.0 + desx_ocb1encryptdone@Base 2.5.0 + desx_ocb1decryptdone@Base 2.5.0 + desx_ocb1@Base 2.5.0 + desx_ocb3init@Base 2.5.0 + desx_ocb3step@Base 2.5.0 + desx_ocb3reinit@Base 2.5.0 + desx_ocb3setkey@Base 2.5.0 + desx_ocb3noncesz@Base 2.5.0 + desx_ocb3aadinit@Base 2.5.0 + desx_ocb3aadhash@Base 2.5.0 + desx_ocb3encrypt@Base 2.5.0 + desx_ocb3decrypt@Base 2.5.0 + desx_ocb3encryptdone@Base 2.5.0 + desx_ocb3decryptdone@Base 2.5.0 + desx_ocb3tagsz@Base 2.5.0 + desx_ocb3@Base 2.5.0 + desx_omacmasks@Base 2.5.0 + desx_omacpolicy@Base 2.5.0 + desx_omacdone@Base 2.5.0 + desx_cmacinit@Base 2.5.0 + desx_cmacsetkey@Base 2.5.0 + desx_cmachash@Base 2.5.0 + desx_cmacdone@Base 2.5.0 + desx_cmac@Base 2.5.0 + desx_pmac1init@Base 2.5.0 + desx_pmac1setkey@Base 2.5.0 + desx_pmac1hash@Base 2.5.0 + desx_pmac1done@Base 2.5.0 + desx_pmac1@Base 2.5.0 ## idea idea_init@Base 2.0.0 @@ -1036,6 +1595,80 @@ libcatacomb.so.2 catacomb2 #MINVER# idea_counterbdry@Base 2.0.0 idea_counter@Base 2.4.3 idea_counterrand@Base 2.0.0 + idea_ccminit@Base 2.5.0 + idea_ccmreinit@Base 2.5.0 + idea_ccmnoncesz@Base 2.5.0 + idea_ccmtagsz@Base 2.5.0 + idea_ccmaadhash@Base 2.5.0 + idea_ccmencrypt@Base 2.5.0 + idea_ccmdecrypt@Base 2.5.0 + idea_ccmencryptdone@Base 2.5.0 + idea_ccmdecryptdone@Base 2.5.0 + idea_ccm@Base 2.5.0 + idea_eaxinit@Base 2.5.0 + idea_eaxreinit@Base 2.5.0 + idea_eaxsetkey@Base 2.5.0 + idea_eaxnoncesz@Base 2.5.0 + idea_eaxtagsz@Base 2.5.0 + idea_eaxaadinit@Base 2.5.0 + idea_eaxaadhash@Base 2.5.0 + idea_eaxencrypt@Base 2.5.0 + idea_eaxdecrypt@Base 2.5.0 + idea_eaxencryptdone@Base 2.5.0 + idea_eaxdecryptdone@Base 2.5.0 + idea_eax@Base 2.5.0 + idea_gcminit@Base 2.5.0 + idea_gcmreinit@Base 2.5.0 + idea_gcmsetkey@Base 2.5.0 + idea_gcmnoncesz@Base 2.5.0 + idea_gcmtagsz@Base 2.5.0 + idea_gcmaadinit@Base 2.5.0 + idea_gcmaadhash@Base 2.5.0 + idea_gcmencrypt@Base 2.5.0 + idea_gcmdecrypt@Base 2.5.0 + idea_gcmencryptdone@Base 2.5.0 + idea_gcmdecryptdone@Base 2.5.0 + idea_gcm@Base 2.5.0 + idea_ocb1init@Base 2.5.0 + idea_ocb1reinit@Base 2.5.0 + idea_ocb1setkey@Base 2.5.0 + idea_ocb1policy@Base 2.5.0 + idea_ocb1noncesz@Base 2.5.0 + idea_ocb1tagsz@Base 2.5.0 + idea_ocb1aadinit@Base 2.5.0 + idea_ocb1aadhash@Base 2.5.0 + idea_ocb1aadtag@Base 2.5.0 + idea_ocb1encrypt@Base 2.5.0 + idea_ocb1decrypt@Base 2.5.0 + idea_ocb1encryptdone@Base 2.5.0 + idea_ocb1decryptdone@Base 2.5.0 + idea_ocb1@Base 2.5.0 + idea_ocb3init@Base 2.5.0 + idea_ocb3step@Base 2.5.0 + idea_ocb3reinit@Base 2.5.0 + idea_ocb3setkey@Base 2.5.0 + idea_ocb3noncesz@Base 2.5.0 + idea_ocb3aadinit@Base 2.5.0 + idea_ocb3aadhash@Base 2.5.0 + idea_ocb3encrypt@Base 2.5.0 + idea_ocb3decrypt@Base 2.5.0 + idea_ocb3encryptdone@Base 2.5.0 + idea_ocb3decryptdone@Base 2.5.0 + idea_ocb3tagsz@Base 2.5.0 + idea_ocb3@Base 2.5.0 + idea_omacmasks@Base 2.5.0 + idea_omacpolicy@Base 2.5.0 + idea_omacdone@Base 2.5.0 + idea_cmacinit@Base 2.5.0 + idea_cmacsetkey@Base 2.5.0 + idea_cmachash@Base 2.5.0 + idea_cmacdone@Base 2.5.0 + idea_cmac@Base 2.5.0 + idea_pmac1init@Base 2.5.0 + idea_pmac1setkey@Base 2.5.0 + idea_pmac1hash@Base 2.5.0 + idea_pmac1done@Base 2.5.0 + idea_pmac1@Base 2.5.0 ## mars mars_init@Base 2.0.0 @@ -1079,6 +1712,80 @@ libcatacomb.so.2 catacomb2 #MINVER# mars_counterbdry@Base 2.0.0 mars_counter@Base 2.0.0 mars_counterrand@Base 2.0.0 + mars_ccminit@Base 2.5.0 + mars_ccmreinit@Base 2.5.0 + mars_ccmnoncesz@Base 2.5.0 + mars_ccmtagsz@Base 2.5.0 + mars_ccmaadhash@Base 2.5.0 + mars_ccmencrypt@Base 2.5.0 + mars_ccmdecrypt@Base 2.5.0 + mars_ccmencryptdone@Base 2.5.0 + mars_ccmdecryptdone@Base 2.5.0 + mars_ccm@Base 2.5.0 + mars_eaxinit@Base 2.5.0 + mars_eaxreinit@Base 2.5.0 + mars_eaxsetkey@Base 2.5.0 + mars_eaxnoncesz@Base 2.5.0 + mars_eaxtagsz@Base 2.5.0 + mars_eaxaadinit@Base 2.5.0 + mars_eaxaadhash@Base 2.5.0 + mars_eaxencrypt@Base 2.5.0 + mars_eaxdecrypt@Base 2.5.0 + mars_eaxencryptdone@Base 2.5.0 + mars_eaxdecryptdone@Base 2.5.0 + mars_eax@Base 2.5.0 + mars_gcminit@Base 2.5.0 + mars_gcmreinit@Base 2.5.0 + mars_gcmsetkey@Base 2.5.0 + mars_gcmnoncesz@Base 2.5.0 + mars_gcmtagsz@Base 2.5.0 + mars_gcmaadinit@Base 2.5.0 + mars_gcmaadhash@Base 2.5.0 + mars_gcmencrypt@Base 2.5.0 + mars_gcmdecrypt@Base 2.5.0 + mars_gcmencryptdone@Base 2.5.0 + mars_gcmdecryptdone@Base 2.5.0 + mars_gcm@Base 2.5.0 + mars_ocb1init@Base 2.5.0 + mars_ocb1reinit@Base 2.5.0 + mars_ocb1setkey@Base 2.5.0 + mars_ocb1policy@Base 2.5.0 + mars_ocb1noncesz@Base 2.5.0 + mars_ocb1tagsz@Base 2.5.0 + mars_ocb1aadinit@Base 2.5.0 + mars_ocb1aadhash@Base 2.5.0 + mars_ocb1aadtag@Base 2.5.0 + mars_ocb1encrypt@Base 2.5.0 + mars_ocb1decrypt@Base 2.5.0 + mars_ocb1encryptdone@Base 2.5.0 + mars_ocb1decryptdone@Base 2.5.0 + mars_ocb1@Base 2.5.0 + mars_ocb3init@Base 2.5.0 + mars_ocb3step@Base 2.5.0 + mars_ocb3reinit@Base 2.5.0 + mars_ocb3setkey@Base 2.5.0 + mars_ocb3noncesz@Base 2.5.0 + mars_ocb3aadinit@Base 2.5.0 + mars_ocb3aadhash@Base 2.5.0 + mars_ocb3encrypt@Base 2.5.0 + mars_ocb3decrypt@Base 2.5.0 + mars_ocb3encryptdone@Base 2.5.0 + mars_ocb3decryptdone@Base 2.5.0 + mars_ocb3tagsz@Base 2.5.0 + mars_ocb3@Base 2.5.0 + mars_omacmasks@Base 2.5.0 + mars_omacpolicy@Base 2.5.0 + mars_omacdone@Base 2.5.0 + mars_cmacinit@Base 2.5.0 + mars_cmacsetkey@Base 2.5.0 + mars_cmachash@Base 2.5.0 + mars_cmacdone@Base 2.5.0 + mars_cmac@Base 2.5.0 + mars_pmac1init@Base 2.5.0 + mars_pmac1setkey@Base 2.5.0 + mars_pmac1hash@Base 2.5.0 + mars_pmac1done@Base 2.5.0 + mars_pmac1@Base 2.5.0 ## noekeon noekeon_init@Base 2.0.0 @@ -1121,6 +1828,80 @@ libcatacomb.so.2 catacomb2 #MINVER# noekeon_counterbdry@Base 2.0.0 noekeon_counter@Base 2.0.0 noekeon_counterrand@Base 2.0.0 + noekeon_ccminit@Base 2.5.0 + noekeon_ccmreinit@Base 2.5.0 + noekeon_ccmnoncesz@Base 2.5.0 + noekeon_ccmtagsz@Base 2.5.0 + noekeon_ccmaadhash@Base 2.5.0 + noekeon_ccmencrypt@Base 2.5.0 + noekeon_ccmdecrypt@Base 2.5.0 + noekeon_ccmencryptdone@Base 2.5.0 + noekeon_ccmdecryptdone@Base 2.5.0 + noekeon_ccm@Base 2.5.0 + noekeon_eaxinit@Base 2.5.0 + noekeon_eaxreinit@Base 2.5.0 + noekeon_eaxsetkey@Base 2.5.0 + noekeon_eaxnoncesz@Base 2.5.0 + noekeon_eaxtagsz@Base 2.5.0 + noekeon_eaxaadinit@Base 2.5.0 + noekeon_eaxaadhash@Base 2.5.0 + noekeon_eaxencrypt@Base 2.5.0 + noekeon_eaxdecrypt@Base 2.5.0 + noekeon_eaxencryptdone@Base 2.5.0 + noekeon_eaxdecryptdone@Base 2.5.0 + noekeon_eax@Base 2.5.0 + noekeon_gcminit@Base 2.5.0 + noekeon_gcmreinit@Base 2.5.0 + noekeon_gcmsetkey@Base 2.5.0 + noekeon_gcmnoncesz@Base 2.5.0 + noekeon_gcmtagsz@Base 2.5.0 + noekeon_gcmaadinit@Base 2.5.0 + noekeon_gcmaadhash@Base 2.5.0 + noekeon_gcmencrypt@Base 2.5.0 + noekeon_gcmdecrypt@Base 2.5.0 + noekeon_gcmencryptdone@Base 2.5.0 + noekeon_gcmdecryptdone@Base 2.5.0 + noekeon_gcm@Base 2.5.0 + noekeon_ocb1init@Base 2.5.0 + noekeon_ocb1reinit@Base 2.5.0 + noekeon_ocb1setkey@Base 2.5.0 + noekeon_ocb1policy@Base 2.5.0 + noekeon_ocb1noncesz@Base 2.5.0 + noekeon_ocb1tagsz@Base 2.5.0 + noekeon_ocb1aadinit@Base 2.5.0 + noekeon_ocb1aadhash@Base 2.5.0 + noekeon_ocb1aadtag@Base 2.5.0 + noekeon_ocb1encrypt@Base 2.5.0 + noekeon_ocb1decrypt@Base 2.5.0 + noekeon_ocb1encryptdone@Base 2.5.0 + noekeon_ocb1decryptdone@Base 2.5.0 + noekeon_ocb1@Base 2.5.0 + noekeon_ocb3init@Base 2.5.0 + noekeon_ocb3step@Base 2.5.0 + noekeon_ocb3reinit@Base 2.5.0 + noekeon_ocb3setkey@Base 2.5.0 + noekeon_ocb3noncesz@Base 2.5.0 + noekeon_ocb3aadinit@Base 2.5.0 + noekeon_ocb3aadhash@Base 2.5.0 + noekeon_ocb3encrypt@Base 2.5.0 + noekeon_ocb3decrypt@Base 2.5.0 + noekeon_ocb3encryptdone@Base 2.5.0 + noekeon_ocb3decryptdone@Base 2.5.0 + noekeon_ocb3tagsz@Base 2.5.0 + noekeon_ocb3@Base 2.5.0 + noekeon_omacmasks@Base 2.5.0 + noekeon_omacpolicy@Base 2.5.0 + noekeon_omacdone@Base 2.5.0 + noekeon_cmacinit@Base 2.5.0 + noekeon_cmacsetkey@Base 2.5.0 + noekeon_cmachash@Base 2.5.0 + noekeon_cmacdone@Base 2.5.0 + noekeon_cmac@Base 2.5.0 + noekeon_pmac1init@Base 2.5.0 + noekeon_pmac1setkey@Base 2.5.0 + noekeon_pmac1hash@Base 2.5.0 + noekeon_pmac1done@Base 2.5.0 + noekeon_pmac1@Base 2.5.0 ## rc2 rc2_init@Base 2.0.0 @@ -1165,6 +1946,80 @@ libcatacomb.so.2 catacomb2 #MINVER# rc2_counterbdry@Base 2.0.0 rc2_counter@Base 2.0.0 rc2_counterrand@Base 2.0.0 + rc2_ccminit@Base 2.5.0 + rc2_ccmreinit@Base 2.5.0 + rc2_ccmnoncesz@Base 2.5.0 + rc2_ccmtagsz@Base 2.5.0 + rc2_ccmaadhash@Base 2.5.0 + rc2_ccmencrypt@Base 2.5.0 + rc2_ccmdecrypt@Base 2.5.0 + rc2_ccmencryptdone@Base 2.5.0 + rc2_ccmdecryptdone@Base 2.5.0 + rc2_ccm@Base 2.5.0 + rc2_eaxinit@Base 2.5.0 + rc2_eaxreinit@Base 2.5.0 + rc2_eaxsetkey@Base 2.5.0 + rc2_eaxnoncesz@Base 2.5.0 + rc2_eaxtagsz@Base 2.5.0 + rc2_eaxaadinit@Base 2.5.0 + rc2_eaxaadhash@Base 2.5.0 + rc2_eaxencrypt@Base 2.5.0 + rc2_eaxdecrypt@Base 2.5.0 + rc2_eaxencryptdone@Base 2.5.0 + rc2_eaxdecryptdone@Base 2.5.0 + rc2_eax@Base 2.5.0 + rc2_gcminit@Base 2.5.0 + rc2_gcmreinit@Base 2.5.0 + rc2_gcmsetkey@Base 2.5.0 + rc2_gcmnoncesz@Base 2.5.0 + rc2_gcmtagsz@Base 2.5.0 + rc2_gcmaadinit@Base 2.5.0 + rc2_gcmaadhash@Base 2.5.0 + rc2_gcmencrypt@Base 2.5.0 + rc2_gcmdecrypt@Base 2.5.0 + rc2_gcmencryptdone@Base 2.5.0 + rc2_gcmdecryptdone@Base 2.5.0 + rc2_gcm@Base 2.5.0 + rc2_ocb1init@Base 2.5.0 + rc2_ocb1reinit@Base 2.5.0 + rc2_ocb1setkey@Base 2.5.0 + rc2_ocb1policy@Base 2.5.0 + rc2_ocb1noncesz@Base 2.5.0 + rc2_ocb1tagsz@Base 2.5.0 + rc2_ocb1aadinit@Base 2.5.0 + rc2_ocb1aadhash@Base 2.5.0 + rc2_ocb1aadtag@Base 2.5.0 + rc2_ocb1encrypt@Base 2.5.0 + rc2_ocb1decrypt@Base 2.5.0 + rc2_ocb1encryptdone@Base 2.5.0 + rc2_ocb1decryptdone@Base 2.5.0 + rc2_ocb1@Base 2.5.0 + rc2_ocb3init@Base 2.5.0 + rc2_ocb3step@Base 2.5.0 + rc2_ocb3reinit@Base 2.5.0 + rc2_ocb3setkey@Base 2.5.0 + rc2_ocb3noncesz@Base 2.5.0 + rc2_ocb3aadinit@Base 2.5.0 + rc2_ocb3aadhash@Base 2.5.0 + rc2_ocb3encrypt@Base 2.5.0 + rc2_ocb3decrypt@Base 2.5.0 + rc2_ocb3encryptdone@Base 2.5.0 + rc2_ocb3decryptdone@Base 2.5.0 + rc2_ocb3tagsz@Base 2.5.0 + rc2_ocb3@Base 2.5.0 + rc2_omacmasks@Base 2.5.0 + rc2_omacpolicy@Base 2.5.0 + rc2_omacdone@Base 2.5.0 + rc2_cmacinit@Base 2.5.0 + rc2_cmacsetkey@Base 2.5.0 + rc2_cmachash@Base 2.5.0 + rc2_cmacdone@Base 2.5.0 + rc2_cmac@Base 2.5.0 + rc2_pmac1init@Base 2.5.0 + rc2_pmac1setkey@Base 2.5.0 + rc2_pmac1hash@Base 2.5.0 + rc2_pmac1done@Base 2.5.0 + rc2_pmac1@Base 2.5.0 ## rc4 rc4_init@Base 2.0.0 @@ -1215,6 +2070,80 @@ libcatacomb.so.2 catacomb2 #MINVER# rc5_counterbdry@Base 2.0.0 rc5_counter@Base 2.0.0 rc5_counterrand@Base 2.0.0 + rc5_ccminit@Base 2.5.0 + rc5_ccmreinit@Base 2.5.0 + rc5_ccmnoncesz@Base 2.5.0 + rc5_ccmtagsz@Base 2.5.0 + rc5_ccmaadhash@Base 2.5.0 + rc5_ccmencrypt@Base 2.5.0 + rc5_ccmdecrypt@Base 2.5.0 + rc5_ccmencryptdone@Base 2.5.0 + rc5_ccmdecryptdone@Base 2.5.0 + rc5_ccm@Base 2.5.0 + rc5_eaxinit@Base 2.5.0 + rc5_eaxreinit@Base 2.5.0 + rc5_eaxsetkey@Base 2.5.0 + rc5_eaxnoncesz@Base 2.5.0 + rc5_eaxtagsz@Base 2.5.0 + rc5_eaxaadinit@Base 2.5.0 + rc5_eaxaadhash@Base 2.5.0 + rc5_eaxencrypt@Base 2.5.0 + rc5_eaxdecrypt@Base 2.5.0 + rc5_eaxencryptdone@Base 2.5.0 + rc5_eaxdecryptdone@Base 2.5.0 + rc5_eax@Base 2.5.0 + rc5_gcminit@Base 2.5.0 + rc5_gcmreinit@Base 2.5.0 + rc5_gcmsetkey@Base 2.5.0 + rc5_gcmnoncesz@Base 2.5.0 + rc5_gcmtagsz@Base 2.5.0 + rc5_gcmaadinit@Base 2.5.0 + rc5_gcmaadhash@Base 2.5.0 + rc5_gcmencrypt@Base 2.5.0 + rc5_gcmdecrypt@Base 2.5.0 + rc5_gcmencryptdone@Base 2.5.0 + rc5_gcmdecryptdone@Base 2.5.0 + rc5_gcm@Base 2.5.0 + rc5_ocb1init@Base 2.5.0 + rc5_ocb1reinit@Base 2.5.0 + rc5_ocb1setkey@Base 2.5.0 + rc5_ocb1policy@Base 2.5.0 + rc5_ocb1noncesz@Base 2.5.0 + rc5_ocb1tagsz@Base 2.5.0 + rc5_ocb1aadinit@Base 2.5.0 + rc5_ocb1aadhash@Base 2.5.0 + rc5_ocb1aadtag@Base 2.5.0 + rc5_ocb1encrypt@Base 2.5.0 + rc5_ocb1decrypt@Base 2.5.0 + rc5_ocb1encryptdone@Base 2.5.0 + rc5_ocb1decryptdone@Base 2.5.0 + rc5_ocb1@Base 2.5.0 + rc5_ocb3init@Base 2.5.0 + rc5_ocb3step@Base 2.5.0 + rc5_ocb3reinit@Base 2.5.0 + rc5_ocb3setkey@Base 2.5.0 + rc5_ocb3noncesz@Base 2.5.0 + rc5_ocb3aadinit@Base 2.5.0 + rc5_ocb3aadhash@Base 2.5.0 + rc5_ocb3encrypt@Base 2.5.0 + rc5_ocb3decrypt@Base 2.5.0 + rc5_ocb3encryptdone@Base 2.5.0 + rc5_ocb3decryptdone@Base 2.5.0 + rc5_ocb3tagsz@Base 2.5.0 + rc5_ocb3@Base 2.5.0 + rc5_omacmasks@Base 2.5.0 + rc5_omacpolicy@Base 2.5.0 + rc5_omacdone@Base 2.5.0 + rc5_cmacinit@Base 2.5.0 + rc5_cmacsetkey@Base 2.5.0 + rc5_cmachash@Base 2.5.0 + rc5_cmacdone@Base 2.5.0 + rc5_cmac@Base 2.5.0 + rc5_pmac1init@Base 2.5.0 + rc5_pmac1setkey@Base 2.5.0 + rc5_pmac1hash@Base 2.5.0 + rc5_pmac1done@Base 2.5.0 + rc5_pmac1@Base 2.5.0 ## rijndael rijndael_init@Base 2.0.0 @@ -1229,12 +2158,15 @@ libcatacomb.so.2 catacomb2 #MINVER# (optional)rijndael_ti@Base 2.1.5 (optional)rijndael_u@Base 2.1.5 (optional|arch=i386 amd64)rijndael_setup_x86ish_aesni@Base 2.3.0 + (optional|arch=i386 amd64)rijndael_setup_x86ish_aesni_avx@Base 2.3.0 (optional|arch=armel armhf)rijndael_setup_arm_crypto@Base 2.2.5 (optional|arch=arm64)rijndael_setup_arm64_crypto@Base 2.4.3 (optional|arch=i386 amd64)rijndael_eblk_x86ish_aesni@Base 2.3.0 + (optional|arch=i386 amd64)rijndael_eblk_x86ish_aesni_avx@Base 2.3.0 (optional|arch=armel armhf)rijndael_eblk_arm_crypto@Base 2.2.5 (optional|arch=arm64)rijndael_eblk_arm64_crypto@Base 2.4.3 (optional|arch=i386 amd64)rijndael_dblk_x86ish_aesni@Base 2.3.0 + (optional|arch=i386 amd64)rijndael_dblk_x86ish_aesni_avx@Base 2.3.0 (optional|arch=armel armhf)rijndael_dblk_arm_crypto@Base 2.2.5 (optional|arch=arm64)rijndael_dblk_arm64_crypto@Base 2.4.3 rijndael_ecbinit@Base 2.1.1 @@ -1273,6 +2205,80 @@ libcatacomb.so.2 catacomb2 #MINVER# rijndael_counterbdry@Base 2.0.0 rijndael_counter@Base 2.0.0 rijndael_counterrand@Base 2.0.0 + rijndael_ccminit@Base 2.5.0 + rijndael_ccmreinit@Base 2.5.0 + rijndael_ccmnoncesz@Base 2.5.0 + rijndael_ccmtagsz@Base 2.5.0 + rijndael_ccmaadhash@Base 2.5.0 + rijndael_ccmencrypt@Base 2.5.0 + rijndael_ccmdecrypt@Base 2.5.0 + rijndael_ccmencryptdone@Base 2.5.0 + rijndael_ccmdecryptdone@Base 2.5.0 + rijndael_ccm@Base 2.5.0 + rijndael_eaxinit@Base 2.5.0 + rijndael_eaxreinit@Base 2.5.0 + rijndael_eaxsetkey@Base 2.5.0 + rijndael_eaxnoncesz@Base 2.5.0 + rijndael_eaxtagsz@Base 2.5.0 + rijndael_eaxaadinit@Base 2.5.0 + rijndael_eaxaadhash@Base 2.5.0 + rijndael_eaxencrypt@Base 2.5.0 + rijndael_eaxdecrypt@Base 2.5.0 + rijndael_eaxencryptdone@Base 2.5.0 + rijndael_eaxdecryptdone@Base 2.5.0 + rijndael_eax@Base 2.5.0 + rijndael_gcminit@Base 2.5.0 + rijndael_gcmreinit@Base 2.5.0 + rijndael_gcmsetkey@Base 2.5.0 + rijndael_gcmnoncesz@Base 2.5.0 + rijndael_gcmtagsz@Base 2.5.0 + rijndael_gcmaadinit@Base 2.5.0 + rijndael_gcmaadhash@Base 2.5.0 + rijndael_gcmencrypt@Base 2.5.0 + rijndael_gcmdecrypt@Base 2.5.0 + rijndael_gcmencryptdone@Base 2.5.0 + rijndael_gcmdecryptdone@Base 2.5.0 + rijndael_gcm@Base 2.5.0 + rijndael_ocb1init@Base 2.5.0 + rijndael_ocb1reinit@Base 2.5.0 + rijndael_ocb1setkey@Base 2.5.0 + rijndael_ocb1policy@Base 2.5.0 + rijndael_ocb1noncesz@Base 2.5.0 + rijndael_ocb1tagsz@Base 2.5.0 + rijndael_ocb1aadinit@Base 2.5.0 + rijndael_ocb1aadhash@Base 2.5.0 + rijndael_ocb1aadtag@Base 2.5.0 + rijndael_ocb1encrypt@Base 2.5.0 + rijndael_ocb1decrypt@Base 2.5.0 + rijndael_ocb1encryptdone@Base 2.5.0 + rijndael_ocb1decryptdone@Base 2.5.0 + rijndael_ocb1@Base 2.5.0 + rijndael_ocb3init@Base 2.5.0 + rijndael_ocb3step@Base 2.5.0 + rijndael_ocb3reinit@Base 2.5.0 + rijndael_ocb3setkey@Base 2.5.0 + rijndael_ocb3noncesz@Base 2.5.0 + rijndael_ocb3aadinit@Base 2.5.0 + rijndael_ocb3aadhash@Base 2.5.0 + rijndael_ocb3encrypt@Base 2.5.0 + rijndael_ocb3decrypt@Base 2.5.0 + rijndael_ocb3encryptdone@Base 2.5.0 + rijndael_ocb3decryptdone@Base 2.5.0 + rijndael_ocb3tagsz@Base 2.5.0 + rijndael_ocb3@Base 2.5.0 + rijndael_omacmasks@Base 2.5.0 + rijndael_omacpolicy@Base 2.5.0 + rijndael_omacdone@Base 2.5.0 + rijndael_cmacinit@Base 2.5.0 + rijndael_cmacsetkey@Base 2.5.0 + rijndael_cmachash@Base 2.5.0 + rijndael_cmacdone@Base 2.5.0 + rijndael_cmac@Base 2.5.0 + rijndael_pmac1init@Base 2.5.0 + rijndael_pmac1setkey@Base 2.5.0 + rijndael_pmac1hash@Base 2.5.0 + rijndael_pmac1done@Base 2.5.0 + rijndael_pmac1@Base 2.5.0 ## rijndael192 rijndael192_init@Base 2.0.0 @@ -1314,6 +2320,80 @@ libcatacomb.so.2 catacomb2 #MINVER# rijndael192_counterbdry@Base 2.0.0 rijndael192_counter@Base 2.0.0 rijndael192_counterrand@Base 2.0.0 + rijndael192_ccminit@Base 2.5.0 + rijndael192_ccmreinit@Base 2.5.0 + rijndael192_ccmnoncesz@Base 2.5.0 + rijndael192_ccmtagsz@Base 2.5.0 + rijndael192_ccmaadhash@Base 2.5.0 + rijndael192_ccmencrypt@Base 2.5.0 + rijndael192_ccmdecrypt@Base 2.5.0 + rijndael192_ccmencryptdone@Base 2.5.0 + rijndael192_ccmdecryptdone@Base 2.5.0 + rijndael192_ccm@Base 2.5.0 + rijndael192_eaxinit@Base 2.5.0 + rijndael192_eaxreinit@Base 2.5.0 + rijndael192_eaxsetkey@Base 2.5.0 + rijndael192_eaxnoncesz@Base 2.5.0 + rijndael192_eaxtagsz@Base 2.5.0 + rijndael192_eaxaadinit@Base 2.5.0 + rijndael192_eaxaadhash@Base 2.5.0 + rijndael192_eaxencrypt@Base 2.5.0 + rijndael192_eaxdecrypt@Base 2.5.0 + rijndael192_eaxencryptdone@Base 2.5.0 + rijndael192_eaxdecryptdone@Base 2.5.0 + rijndael192_eax@Base 2.5.0 + rijndael192_gcminit@Base 2.5.0 + rijndael192_gcmreinit@Base 2.5.0 + rijndael192_gcmsetkey@Base 2.5.0 + rijndael192_gcmnoncesz@Base 2.5.0 + rijndael192_gcmtagsz@Base 2.5.0 + rijndael192_gcmaadinit@Base 2.5.0 + rijndael192_gcmaadhash@Base 2.5.0 + rijndael192_gcmencrypt@Base 2.5.0 + rijndael192_gcmdecrypt@Base 2.5.0 + rijndael192_gcmencryptdone@Base 2.5.0 + rijndael192_gcmdecryptdone@Base 2.5.0 + rijndael192_gcm@Base 2.5.0 + rijndael192_ocb1init@Base 2.5.0 + rijndael192_ocb1reinit@Base 2.5.0 + rijndael192_ocb1setkey@Base 2.5.0 + rijndael192_ocb1policy@Base 2.5.0 + rijndael192_ocb1noncesz@Base 2.5.0 + rijndael192_ocb1tagsz@Base 2.5.0 + rijndael192_ocb1aadinit@Base 2.5.0 + rijndael192_ocb1aadhash@Base 2.5.0 + rijndael192_ocb1aadtag@Base 2.5.0 + rijndael192_ocb1encrypt@Base 2.5.0 + rijndael192_ocb1decrypt@Base 2.5.0 + rijndael192_ocb1encryptdone@Base 2.5.0 + rijndael192_ocb1decryptdone@Base 2.5.0 + rijndael192_ocb1@Base 2.5.0 + rijndael192_ocb3init@Base 2.5.0 + rijndael192_ocb3step@Base 2.5.0 + rijndael192_ocb3reinit@Base 2.5.0 + rijndael192_ocb3setkey@Base 2.5.0 + rijndael192_ocb3noncesz@Base 2.5.0 + rijndael192_ocb3aadinit@Base 2.5.0 + rijndael192_ocb3aadhash@Base 2.5.0 + rijndael192_ocb3encrypt@Base 2.5.0 + rijndael192_ocb3decrypt@Base 2.5.0 + rijndael192_ocb3encryptdone@Base 2.5.0 + rijndael192_ocb3decryptdone@Base 2.5.0 + rijndael192_ocb3tagsz@Base 2.5.0 + rijndael192_ocb3@Base 2.5.0 + rijndael192_omacmasks@Base 2.5.0 + rijndael192_omacpolicy@Base 2.5.0 + rijndael192_omacdone@Base 2.5.0 + rijndael192_cmacinit@Base 2.5.0 + rijndael192_cmacsetkey@Base 2.5.0 + rijndael192_cmachash@Base 2.5.0 + rijndael192_cmacdone@Base 2.5.0 + rijndael192_cmac@Base 2.5.0 + rijndael192_pmac1init@Base 2.5.0 + rijndael192_pmac1setkey@Base 2.5.0 + rijndael192_pmac1hash@Base 2.5.0 + rijndael192_pmac1done@Base 2.5.0 + rijndael192_pmac1@Base 2.5.0 ## rijndael256 rijndael256_init@Base 2.0.0 @@ -1355,6 +2435,80 @@ libcatacomb.so.2 catacomb2 #MINVER# rijndael256_counterbdry@Base 2.0.0 rijndael256_counter@Base 2.0.0 rijndael256_counterrand@Base 2.0.0 + rijndael256_ccminit@Base 2.5.0 + rijndael256_ccmreinit@Base 2.5.0 + rijndael256_ccmnoncesz@Base 2.5.0 + rijndael256_ccmtagsz@Base 2.5.0 + rijndael256_ccmaadhash@Base 2.5.0 + rijndael256_ccmencrypt@Base 2.5.0 + rijndael256_ccmdecrypt@Base 2.5.0 + rijndael256_ccmencryptdone@Base 2.5.0 + rijndael256_ccmdecryptdone@Base 2.5.0 + rijndael256_ccm@Base 2.5.0 + rijndael256_eaxinit@Base 2.5.0 + rijndael256_eaxreinit@Base 2.5.0 + rijndael256_eaxsetkey@Base 2.5.0 + rijndael256_eaxnoncesz@Base 2.5.0 + rijndael256_eaxtagsz@Base 2.5.0 + rijndael256_eaxaadinit@Base 2.5.0 + rijndael256_eaxaadhash@Base 2.5.0 + rijndael256_eaxencrypt@Base 2.5.0 + rijndael256_eaxdecrypt@Base 2.5.0 + rijndael256_eaxencryptdone@Base 2.5.0 + rijndael256_eaxdecryptdone@Base 2.5.0 + rijndael256_eax@Base 2.5.0 + rijndael256_gcminit@Base 2.5.0 + rijndael256_gcmreinit@Base 2.5.0 + rijndael256_gcmsetkey@Base 2.5.0 + rijndael256_gcmnoncesz@Base 2.5.0 + rijndael256_gcmtagsz@Base 2.5.0 + rijndael256_gcmaadinit@Base 2.5.0 + rijndael256_gcmaadhash@Base 2.5.0 + rijndael256_gcmencrypt@Base 2.5.0 + rijndael256_gcmdecrypt@Base 2.5.0 + rijndael256_gcmencryptdone@Base 2.5.0 + rijndael256_gcmdecryptdone@Base 2.5.0 + rijndael256_gcm@Base 2.5.0 + rijndael256_ocb1init@Base 2.5.0 + rijndael256_ocb1reinit@Base 2.5.0 + rijndael256_ocb1setkey@Base 2.5.0 + rijndael256_ocb1policy@Base 2.5.0 + rijndael256_ocb1noncesz@Base 2.5.0 + rijndael256_ocb1tagsz@Base 2.5.0 + rijndael256_ocb1aadinit@Base 2.5.0 + rijndael256_ocb1aadhash@Base 2.5.0 + rijndael256_ocb1aadtag@Base 2.5.0 + rijndael256_ocb1encrypt@Base 2.5.0 + rijndael256_ocb1decrypt@Base 2.5.0 + rijndael256_ocb1encryptdone@Base 2.5.0 + rijndael256_ocb1decryptdone@Base 2.5.0 + rijndael256_ocb1@Base 2.5.0 + rijndael256_ocb3init@Base 2.5.0 + rijndael256_ocb3step@Base 2.5.0 + rijndael256_ocb3reinit@Base 2.5.0 + rijndael256_ocb3setkey@Base 2.5.0 + rijndael256_ocb3noncesz@Base 2.5.0 + rijndael256_ocb3aadinit@Base 2.5.0 + rijndael256_ocb3aadhash@Base 2.5.0 + rijndael256_ocb3encrypt@Base 2.5.0 + rijndael256_ocb3decrypt@Base 2.5.0 + rijndael256_ocb3encryptdone@Base 2.5.0 + rijndael256_ocb3decryptdone@Base 2.5.0 + rijndael256_ocb3tagsz@Base 2.5.0 + rijndael256_ocb3@Base 2.5.0 + rijndael256_omacmasks@Base 2.5.0 + rijndael256_omacpolicy@Base 2.5.0 + rijndael256_omacdone@Base 2.5.0 + rijndael256_cmacinit@Base 2.5.0 + rijndael256_cmacsetkey@Base 2.5.0 + rijndael256_cmachash@Base 2.5.0 + rijndael256_cmacdone@Base 2.5.0 + rijndael256_cmac@Base 2.5.0 + rijndael256_pmac1init@Base 2.5.0 + rijndael256_pmac1setkey@Base 2.5.0 + rijndael256_pmac1hash@Base 2.5.0 + rijndael256_pmac1done@Base 2.5.0 + rijndael256_pmac1@Base 2.5.0 ## safer safer_init@Base 2.0.0 @@ -1400,6 +2554,80 @@ libcatacomb.so.2 catacomb2 #MINVER# safer_counterbdry@Base 2.0.0 safer_counter@Base 2.0.0 safer_counterrand@Base 2.0.0 + safer_ccminit@Base 2.5.0 + safer_ccmreinit@Base 2.5.0 + safer_ccmnoncesz@Base 2.5.0 + safer_ccmtagsz@Base 2.5.0 + safer_ccmaadhash@Base 2.5.0 + safer_ccmencrypt@Base 2.5.0 + safer_ccmdecrypt@Base 2.5.0 + safer_ccmencryptdone@Base 2.5.0 + safer_ccmdecryptdone@Base 2.5.0 + safer_ccm@Base 2.5.0 + safer_eaxinit@Base 2.5.0 + safer_eaxreinit@Base 2.5.0 + safer_eaxsetkey@Base 2.5.0 + safer_eaxnoncesz@Base 2.5.0 + safer_eaxtagsz@Base 2.5.0 + safer_eaxaadinit@Base 2.5.0 + safer_eaxaadhash@Base 2.5.0 + safer_eaxencrypt@Base 2.5.0 + safer_eaxdecrypt@Base 2.5.0 + safer_eaxencryptdone@Base 2.5.0 + safer_eaxdecryptdone@Base 2.5.0 + safer_eax@Base 2.5.0 + safer_gcminit@Base 2.5.0 + safer_gcmreinit@Base 2.5.0 + safer_gcmsetkey@Base 2.5.0 + safer_gcmnoncesz@Base 2.5.0 + safer_gcmtagsz@Base 2.5.0 + safer_gcmaadinit@Base 2.5.0 + safer_gcmaadhash@Base 2.5.0 + safer_gcmencrypt@Base 2.5.0 + safer_gcmdecrypt@Base 2.5.0 + safer_gcmencryptdone@Base 2.5.0 + safer_gcmdecryptdone@Base 2.5.0 + safer_gcm@Base 2.5.0 + safer_ocb1init@Base 2.5.0 + safer_ocb1reinit@Base 2.5.0 + safer_ocb1setkey@Base 2.5.0 + safer_ocb1policy@Base 2.5.0 + safer_ocb1noncesz@Base 2.5.0 + safer_ocb1tagsz@Base 2.5.0 + safer_ocb1aadinit@Base 2.5.0 + safer_ocb1aadhash@Base 2.5.0 + safer_ocb1aadtag@Base 2.5.0 + safer_ocb1encrypt@Base 2.5.0 + safer_ocb1decrypt@Base 2.5.0 + safer_ocb1encryptdone@Base 2.5.0 + safer_ocb1decryptdone@Base 2.5.0 + safer_ocb1@Base 2.5.0 + safer_ocb3init@Base 2.5.0 + safer_ocb3step@Base 2.5.0 + safer_ocb3reinit@Base 2.5.0 + safer_ocb3setkey@Base 2.5.0 + safer_ocb3noncesz@Base 2.5.0 + safer_ocb3aadinit@Base 2.5.0 + safer_ocb3aadhash@Base 2.5.0 + safer_ocb3encrypt@Base 2.5.0 + safer_ocb3decrypt@Base 2.5.0 + safer_ocb3encryptdone@Base 2.5.0 + safer_ocb3decryptdone@Base 2.5.0 + safer_ocb3tagsz@Base 2.5.0 + safer_ocb3@Base 2.5.0 + safer_omacmasks@Base 2.5.0 + safer_omacpolicy@Base 2.5.0 + safer_omacdone@Base 2.5.0 + safer_cmacinit@Base 2.5.0 + safer_cmacsetkey@Base 2.5.0 + safer_cmachash@Base 2.5.0 + safer_cmacdone@Base 2.5.0 + safer_cmac@Base 2.5.0 + safer_pmac1init@Base 2.5.0 + safer_pmac1setkey@Base 2.5.0 + safer_pmac1hash@Base 2.5.0 + safer_pmac1done@Base 2.5.0 + safer_pmac1@Base 2.5.0 ## safersk safersk_init@Base 2.0.0 @@ -1439,6 +2667,80 @@ libcatacomb.so.2 catacomb2 #MINVER# safersk_counterbdry@Base 2.0.0 safersk_counter@Base 2.0.0 safersk_counterrand@Base 2.0.0 + safersk_ccminit@Base 2.5.0 + safersk_ccmreinit@Base 2.5.0 + safersk_ccmnoncesz@Base 2.5.0 + safersk_ccmtagsz@Base 2.5.0 + safersk_ccmaadhash@Base 2.5.0 + safersk_ccmencrypt@Base 2.5.0 + safersk_ccmdecrypt@Base 2.5.0 + safersk_ccmencryptdone@Base 2.5.0 + safersk_ccmdecryptdone@Base 2.5.0 + safersk_ccm@Base 2.5.0 + safersk_eaxinit@Base 2.5.0 + safersk_eaxreinit@Base 2.5.0 + safersk_eaxsetkey@Base 2.5.0 + safersk_eaxnoncesz@Base 2.5.0 + safersk_eaxtagsz@Base 2.5.0 + safersk_eaxaadinit@Base 2.5.0 + safersk_eaxaadhash@Base 2.5.0 + safersk_eaxencrypt@Base 2.5.0 + safersk_eaxdecrypt@Base 2.5.0 + safersk_eaxencryptdone@Base 2.5.0 + safersk_eaxdecryptdone@Base 2.5.0 + safersk_eax@Base 2.5.0 + safersk_gcminit@Base 2.5.0 + safersk_gcmreinit@Base 2.5.0 + safersk_gcmsetkey@Base 2.5.0 + safersk_gcmnoncesz@Base 2.5.0 + safersk_gcmtagsz@Base 2.5.0 + safersk_gcmaadinit@Base 2.5.0 + safersk_gcmaadhash@Base 2.5.0 + safersk_gcmencrypt@Base 2.5.0 + safersk_gcmdecrypt@Base 2.5.0 + safersk_gcmencryptdone@Base 2.5.0 + safersk_gcmdecryptdone@Base 2.5.0 + safersk_gcm@Base 2.5.0 + safersk_ocb1init@Base 2.5.0 + safersk_ocb1reinit@Base 2.5.0 + safersk_ocb1setkey@Base 2.5.0 + safersk_ocb1policy@Base 2.5.0 + safersk_ocb1noncesz@Base 2.5.0 + safersk_ocb1tagsz@Base 2.5.0 + safersk_ocb1aadinit@Base 2.5.0 + safersk_ocb1aadhash@Base 2.5.0 + safersk_ocb1aadtag@Base 2.5.0 + safersk_ocb1encrypt@Base 2.5.0 + safersk_ocb1decrypt@Base 2.5.0 + safersk_ocb1encryptdone@Base 2.5.0 + safersk_ocb1decryptdone@Base 2.5.0 + safersk_ocb1@Base 2.5.0 + safersk_ocb3init@Base 2.5.0 + safersk_ocb3step@Base 2.5.0 + safersk_ocb3reinit@Base 2.5.0 + safersk_ocb3setkey@Base 2.5.0 + safersk_ocb3noncesz@Base 2.5.0 + safersk_ocb3aadinit@Base 2.5.0 + safersk_ocb3aadhash@Base 2.5.0 + safersk_ocb3encrypt@Base 2.5.0 + safersk_ocb3decrypt@Base 2.5.0 + safersk_ocb3encryptdone@Base 2.5.0 + safersk_ocb3decryptdone@Base 2.5.0 + safersk_ocb3tagsz@Base 2.5.0 + safersk_ocb3@Base 2.5.0 + safersk_omacmasks@Base 2.5.0 + safersk_omacpolicy@Base 2.5.0 + safersk_omacdone@Base 2.5.0 + safersk_cmacinit@Base 2.5.0 + safersk_cmacsetkey@Base 2.5.0 + safersk_cmachash@Base 2.5.0 + safersk_cmacdone@Base 2.5.0 + safersk_cmac@Base 2.5.0 + safersk_pmac1init@Base 2.5.0 + safersk_pmac1setkey@Base 2.5.0 + safersk_pmac1hash@Base 2.5.0 + safersk_pmac1done@Base 2.5.0 + safersk_pmac1@Base 2.5.0 ## salsa20 salsa20_init@Base 2.2.0 @@ -1455,6 +2757,7 @@ libcatacomb.so.2 catacomb2 #MINVER# salsa2012_encrypt@Base 2.2.0 salsa20_encrypt@Base 2.2.0 (optional|arch=i386 amd64)salsa20_core_x86ish_sse2@Base 2.2.3 + (optional|arch=i386 amd64)salsa20_core_x86ish_avx@Base 2.2.3 (optional|arch=armel armhf)salsa20_core_arm_neon@Base 2.2.3 (optional|arch=arm64)salsa20_core_arm64@Base 2.4.3 salsa208@Base 2.2.0 @@ -1469,6 +2772,12 @@ libcatacomb.so.2 catacomb2 #MINVER# salsa208_ietf_rand@Base 2.4.2 salsa2012_ietf_rand@Base 2.4.2 salsa20_ietf_rand@Base 2.4.2 + salsa208_naclbox@Base 2.5.0 + salsa2012_naclbox@Base 2.5.0 + salsa20_naclbox@Base 2.5.0 + salsa208_poly1305@Base 2.5.0 + salsa2012_poly1305@Base 2.5.0 + salsa20_poly1305@Base 2.5.0 hsalsa208_prf@Base 2.2.0 hsalsa2012_prf@Base 2.2.0 hsalsa20_prf@Base 2.2.0 @@ -1549,6 +2858,80 @@ libcatacomb.so.2 catacomb2 #MINVER# serpent_counterbdry@Base 2.0.0 serpent_counter@Base 2.0.0 serpent_counterrand@Base 2.0.0 + serpent_ccminit@Base 2.5.0 + serpent_ccmreinit@Base 2.5.0 + serpent_ccmnoncesz@Base 2.5.0 + serpent_ccmtagsz@Base 2.5.0 + serpent_ccmaadhash@Base 2.5.0 + serpent_ccmencrypt@Base 2.5.0 + serpent_ccmdecrypt@Base 2.5.0 + serpent_ccmencryptdone@Base 2.5.0 + serpent_ccmdecryptdone@Base 2.5.0 + serpent_ccm@Base 2.5.0 + serpent_eaxinit@Base 2.5.0 + serpent_eaxreinit@Base 2.5.0 + serpent_eaxsetkey@Base 2.5.0 + serpent_eaxnoncesz@Base 2.5.0 + serpent_eaxtagsz@Base 2.5.0 + serpent_eaxaadinit@Base 2.5.0 + serpent_eaxaadhash@Base 2.5.0 + serpent_eaxencrypt@Base 2.5.0 + serpent_eaxdecrypt@Base 2.5.0 + serpent_eaxencryptdone@Base 2.5.0 + serpent_eaxdecryptdone@Base 2.5.0 + serpent_eax@Base 2.5.0 + serpent_gcminit@Base 2.5.0 + serpent_gcmreinit@Base 2.5.0 + serpent_gcmsetkey@Base 2.5.0 + serpent_gcmnoncesz@Base 2.5.0 + serpent_gcmtagsz@Base 2.5.0 + serpent_gcmaadinit@Base 2.5.0 + serpent_gcmaadhash@Base 2.5.0 + serpent_gcmencrypt@Base 2.5.0 + serpent_gcmdecrypt@Base 2.5.0 + serpent_gcmencryptdone@Base 2.5.0 + serpent_gcmdecryptdone@Base 2.5.0 + serpent_gcm@Base 2.5.0 + serpent_ocb1init@Base 2.5.0 + serpent_ocb1reinit@Base 2.5.0 + serpent_ocb1setkey@Base 2.5.0 + serpent_ocb1policy@Base 2.5.0 + serpent_ocb1noncesz@Base 2.5.0 + serpent_ocb1tagsz@Base 2.5.0 + serpent_ocb1aadinit@Base 2.5.0 + serpent_ocb1aadhash@Base 2.5.0 + serpent_ocb1aadtag@Base 2.5.0 + serpent_ocb1encrypt@Base 2.5.0 + serpent_ocb1decrypt@Base 2.5.0 + serpent_ocb1encryptdone@Base 2.5.0 + serpent_ocb1decryptdone@Base 2.5.0 + serpent_ocb1@Base 2.5.0 + serpent_ocb3init@Base 2.5.0 + serpent_ocb3step@Base 2.5.0 + serpent_ocb3reinit@Base 2.5.0 + serpent_ocb3setkey@Base 2.5.0 + serpent_ocb3noncesz@Base 2.5.0 + serpent_ocb3aadinit@Base 2.5.0 + serpent_ocb3aadhash@Base 2.5.0 + serpent_ocb3encrypt@Base 2.5.0 + serpent_ocb3decrypt@Base 2.5.0 + serpent_ocb3encryptdone@Base 2.5.0 + serpent_ocb3decryptdone@Base 2.5.0 + serpent_ocb3tagsz@Base 2.5.0 + serpent_ocb3@Base 2.5.0 + serpent_omacmasks@Base 2.5.0 + serpent_omacpolicy@Base 2.5.0 + serpent_omacdone@Base 2.5.0 + serpent_cmacinit@Base 2.5.0 + serpent_cmacsetkey@Base 2.5.0 + serpent_cmachash@Base 2.5.0 + serpent_cmacdone@Base 2.5.0 + serpent_cmac@Base 2.5.0 + serpent_pmac1init@Base 2.5.0 + serpent_pmac1setkey@Base 2.5.0 + serpent_pmac1hash@Base 2.5.0 + serpent_pmac1done@Base 2.5.0 + serpent_pmac1@Base 2.5.0 ## skipjack skipjack_init@Base 2.0.0 @@ -1592,6 +2975,80 @@ libcatacomb.so.2 catacomb2 #MINVER# skipjack_counterbdry@Base 2.0.0 skipjack_counter@Base 2.0.0 skipjack_counterrand@Base 2.0.0 + skipjack_ccminit@Base 2.5.0 + skipjack_ccmreinit@Base 2.5.0 + skipjack_ccmnoncesz@Base 2.5.0 + skipjack_ccmtagsz@Base 2.5.0 + skipjack_ccmaadhash@Base 2.5.0 + skipjack_ccmencrypt@Base 2.5.0 + skipjack_ccmdecrypt@Base 2.5.0 + skipjack_ccmencryptdone@Base 2.5.0 + skipjack_ccmdecryptdone@Base 2.5.0 + skipjack_ccm@Base 2.5.0 + skipjack_eaxinit@Base 2.5.0 + skipjack_eaxreinit@Base 2.5.0 + skipjack_eaxsetkey@Base 2.5.0 + skipjack_eaxnoncesz@Base 2.5.0 + skipjack_eaxtagsz@Base 2.5.0 + skipjack_eaxaadinit@Base 2.5.0 + skipjack_eaxaadhash@Base 2.5.0 + skipjack_eaxencrypt@Base 2.5.0 + skipjack_eaxdecrypt@Base 2.5.0 + skipjack_eaxencryptdone@Base 2.5.0 + skipjack_eaxdecryptdone@Base 2.5.0 + skipjack_eax@Base 2.5.0 + skipjack_gcminit@Base 2.5.0 + skipjack_gcmreinit@Base 2.5.0 + skipjack_gcmsetkey@Base 2.5.0 + skipjack_gcmnoncesz@Base 2.5.0 + skipjack_gcmtagsz@Base 2.5.0 + skipjack_gcmaadinit@Base 2.5.0 + skipjack_gcmaadhash@Base 2.5.0 + skipjack_gcmencrypt@Base 2.5.0 + skipjack_gcmdecrypt@Base 2.5.0 + skipjack_gcmencryptdone@Base 2.5.0 + skipjack_gcmdecryptdone@Base 2.5.0 + skipjack_gcm@Base 2.5.0 + skipjack_ocb1init@Base 2.5.0 + skipjack_ocb1reinit@Base 2.5.0 + skipjack_ocb1setkey@Base 2.5.0 + skipjack_ocb1policy@Base 2.5.0 + skipjack_ocb1noncesz@Base 2.5.0 + skipjack_ocb1tagsz@Base 2.5.0 + skipjack_ocb1aadinit@Base 2.5.0 + skipjack_ocb1aadhash@Base 2.5.0 + skipjack_ocb1aadtag@Base 2.5.0 + skipjack_ocb1encrypt@Base 2.5.0 + skipjack_ocb1decrypt@Base 2.5.0 + skipjack_ocb1encryptdone@Base 2.5.0 + skipjack_ocb1decryptdone@Base 2.5.0 + skipjack_ocb1@Base 2.5.0 + skipjack_ocb3init@Base 2.5.0 + skipjack_ocb3step@Base 2.5.0 + skipjack_ocb3reinit@Base 2.5.0 + skipjack_ocb3setkey@Base 2.5.0 + skipjack_ocb3noncesz@Base 2.5.0 + skipjack_ocb3aadinit@Base 2.5.0 + skipjack_ocb3aadhash@Base 2.5.0 + skipjack_ocb3encrypt@Base 2.5.0 + skipjack_ocb3decrypt@Base 2.5.0 + skipjack_ocb3encryptdone@Base 2.5.0 + skipjack_ocb3decryptdone@Base 2.5.0 + skipjack_ocb3tagsz@Base 2.5.0 + skipjack_ocb3@Base 2.5.0 + skipjack_omacmasks@Base 2.5.0 + skipjack_omacpolicy@Base 2.5.0 + skipjack_omacdone@Base 2.5.0 + skipjack_cmacinit@Base 2.5.0 + skipjack_cmacsetkey@Base 2.5.0 + skipjack_cmachash@Base 2.5.0 + skipjack_cmacdone@Base 2.5.0 + skipjack_cmac@Base 2.5.0 + skipjack_pmac1init@Base 2.5.0 + skipjack_pmac1setkey@Base 2.5.0 + skipjack_pmac1hash@Base 2.5.0 + skipjack_pmac1done@Base 2.5.0 + skipjack_pmac1@Base 2.5.0 ## square square_init@Base 2.0.0 @@ -1640,6 +3097,80 @@ libcatacomb.so.2 catacomb2 #MINVER# square_counterbdry@Base 2.0.0 square_counter@Base 2.0.0 square_counterrand@Base 2.0.0 + square_ccminit@Base 2.5.0 + square_ccmreinit@Base 2.5.0 + square_ccmnoncesz@Base 2.5.0 + square_ccmtagsz@Base 2.5.0 + square_ccmaadhash@Base 2.5.0 + square_ccmencrypt@Base 2.5.0 + square_ccmdecrypt@Base 2.5.0 + square_ccmencryptdone@Base 2.5.0 + square_ccmdecryptdone@Base 2.5.0 + square_ccm@Base 2.5.0 + square_eaxinit@Base 2.5.0 + square_eaxreinit@Base 2.5.0 + square_eaxsetkey@Base 2.5.0 + square_eaxnoncesz@Base 2.5.0 + square_eaxtagsz@Base 2.5.0 + square_eaxaadinit@Base 2.5.0 + square_eaxaadhash@Base 2.5.0 + square_eaxencrypt@Base 2.5.0 + square_eaxdecrypt@Base 2.5.0 + square_eaxencryptdone@Base 2.5.0 + square_eaxdecryptdone@Base 2.5.0 + square_eax@Base 2.5.0 + square_gcminit@Base 2.5.0 + square_gcmreinit@Base 2.5.0 + square_gcmsetkey@Base 2.5.0 + square_gcmnoncesz@Base 2.5.0 + square_gcmtagsz@Base 2.5.0 + square_gcmaadinit@Base 2.5.0 + square_gcmaadhash@Base 2.5.0 + square_gcmencrypt@Base 2.5.0 + square_gcmdecrypt@Base 2.5.0 + square_gcmencryptdone@Base 2.5.0 + square_gcmdecryptdone@Base 2.5.0 + square_gcm@Base 2.5.0 + square_ocb1init@Base 2.5.0 + square_ocb1reinit@Base 2.5.0 + square_ocb1setkey@Base 2.5.0 + square_ocb1policy@Base 2.5.0 + square_ocb1noncesz@Base 2.5.0 + square_ocb1tagsz@Base 2.5.0 + square_ocb1aadinit@Base 2.5.0 + square_ocb1aadhash@Base 2.5.0 + square_ocb1aadtag@Base 2.5.0 + square_ocb1encrypt@Base 2.5.0 + square_ocb1decrypt@Base 2.5.0 + square_ocb1encryptdone@Base 2.5.0 + square_ocb1decryptdone@Base 2.5.0 + square_ocb1@Base 2.5.0 + square_ocb3init@Base 2.5.0 + square_ocb3step@Base 2.5.0 + square_ocb3reinit@Base 2.5.0 + square_ocb3setkey@Base 2.5.0 + square_ocb3noncesz@Base 2.5.0 + square_ocb3aadinit@Base 2.5.0 + square_ocb3aadhash@Base 2.5.0 + square_ocb3encrypt@Base 2.5.0 + square_ocb3decrypt@Base 2.5.0 + square_ocb3encryptdone@Base 2.5.0 + square_ocb3decryptdone@Base 2.5.0 + square_ocb3tagsz@Base 2.5.0 + square_ocb3@Base 2.5.0 + square_omacmasks@Base 2.5.0 + square_omacpolicy@Base 2.5.0 + square_omacdone@Base 2.5.0 + square_cmacinit@Base 2.5.0 + square_cmacsetkey@Base 2.5.0 + square_cmachash@Base 2.5.0 + square_cmacdone@Base 2.5.0 + square_cmac@Base 2.5.0 + square_pmac1init@Base 2.5.0 + square_pmac1setkey@Base 2.5.0 + square_pmac1hash@Base 2.5.0 + square_pmac1done@Base 2.5.0 + square_pmac1@Base 2.5.0 ## tea tea_init@Base 2.0.0 @@ -1682,6 +3213,80 @@ libcatacomb.so.2 catacomb2 #MINVER# tea_counterbdry@Base 2.0.0 tea_counter@Base 2.0.0 tea_counterrand@Base 2.0.0 + tea_ccminit@Base 2.5.0 + tea_ccmreinit@Base 2.5.0 + tea_ccmnoncesz@Base 2.5.0 + tea_ccmtagsz@Base 2.5.0 + tea_ccmaadhash@Base 2.5.0 + tea_ccmencrypt@Base 2.5.0 + tea_ccmdecrypt@Base 2.5.0 + tea_ccmencryptdone@Base 2.5.0 + tea_ccmdecryptdone@Base 2.5.0 + tea_ccm@Base 2.5.0 + tea_eaxinit@Base 2.5.0 + tea_eaxreinit@Base 2.5.0 + tea_eaxsetkey@Base 2.5.0 + tea_eaxnoncesz@Base 2.5.0 + tea_eaxtagsz@Base 2.5.0 + tea_eaxaadinit@Base 2.5.0 + tea_eaxaadhash@Base 2.5.0 + tea_eaxencrypt@Base 2.5.0 + tea_eaxdecrypt@Base 2.5.0 + tea_eaxencryptdone@Base 2.5.0 + tea_eaxdecryptdone@Base 2.5.0 + tea_eax@Base 2.5.0 + tea_gcminit@Base 2.5.0 + tea_gcmreinit@Base 2.5.0 + tea_gcmsetkey@Base 2.5.0 + tea_gcmnoncesz@Base 2.5.0 + tea_gcmtagsz@Base 2.5.0 + tea_gcmaadinit@Base 2.5.0 + tea_gcmaadhash@Base 2.5.0 + tea_gcmencrypt@Base 2.5.0 + tea_gcmdecrypt@Base 2.5.0 + tea_gcmencryptdone@Base 2.5.0 + tea_gcmdecryptdone@Base 2.5.0 + tea_gcm@Base 2.5.0 + tea_ocb1init@Base 2.5.0 + tea_ocb1reinit@Base 2.5.0 + tea_ocb1setkey@Base 2.5.0 + tea_ocb1policy@Base 2.5.0 + tea_ocb1noncesz@Base 2.5.0 + tea_ocb1tagsz@Base 2.5.0 + tea_ocb1aadinit@Base 2.5.0 + tea_ocb1aadhash@Base 2.5.0 + tea_ocb1aadtag@Base 2.5.0 + tea_ocb1encrypt@Base 2.5.0 + tea_ocb1decrypt@Base 2.5.0 + tea_ocb1encryptdone@Base 2.5.0 + tea_ocb1decryptdone@Base 2.5.0 + tea_ocb1@Base 2.5.0 + tea_ocb3init@Base 2.5.0 + tea_ocb3step@Base 2.5.0 + tea_ocb3reinit@Base 2.5.0 + tea_ocb3setkey@Base 2.5.0 + tea_ocb3noncesz@Base 2.5.0 + tea_ocb3aadinit@Base 2.5.0 + tea_ocb3aadhash@Base 2.5.0 + tea_ocb3encrypt@Base 2.5.0 + tea_ocb3decrypt@Base 2.5.0 + tea_ocb3encryptdone@Base 2.5.0 + tea_ocb3decryptdone@Base 2.5.0 + tea_ocb3tagsz@Base 2.5.0 + tea_ocb3@Base 2.5.0 + tea_omacmasks@Base 2.5.0 + tea_omacpolicy@Base 2.5.0 + tea_omacdone@Base 2.5.0 + tea_cmacinit@Base 2.5.0 + tea_cmacsetkey@Base 2.5.0 + tea_cmachash@Base 2.5.0 + tea_cmacdone@Base 2.5.0 + tea_cmac@Base 2.5.0 + tea_pmac1init@Base 2.5.0 + tea_pmac1setkey@Base 2.5.0 + tea_pmac1hash@Base 2.5.0 + tea_pmac1done@Base 2.5.0 + tea_pmac1@Base 2.5.0 ## twofish twofish_fkinit@Base 2.0.0 @@ -1732,6 +3337,80 @@ libcatacomb.so.2 catacomb2 #MINVER# twofish_counterbdry@Base 2.0.0 twofish_counter@Base 2.0.0 twofish_counterrand@Base 2.0.0 + twofish_ccminit@Base 2.5.0 + twofish_ccmreinit@Base 2.5.0 + twofish_ccmnoncesz@Base 2.5.0 + twofish_ccmtagsz@Base 2.5.0 + twofish_ccmaadhash@Base 2.5.0 + twofish_ccmencrypt@Base 2.5.0 + twofish_ccmdecrypt@Base 2.5.0 + twofish_ccmencryptdone@Base 2.5.0 + twofish_ccmdecryptdone@Base 2.5.0 + twofish_ccm@Base 2.5.0 + twofish_eaxinit@Base 2.5.0 + twofish_eaxreinit@Base 2.5.0 + twofish_eaxsetkey@Base 2.5.0 + twofish_eaxnoncesz@Base 2.5.0 + twofish_eaxtagsz@Base 2.5.0 + twofish_eaxaadinit@Base 2.5.0 + twofish_eaxaadhash@Base 2.5.0 + twofish_eaxencrypt@Base 2.5.0 + twofish_eaxdecrypt@Base 2.5.0 + twofish_eaxencryptdone@Base 2.5.0 + twofish_eaxdecryptdone@Base 2.5.0 + twofish_eax@Base 2.5.0 + twofish_gcminit@Base 2.5.0 + twofish_gcmreinit@Base 2.5.0 + twofish_gcmsetkey@Base 2.5.0 + twofish_gcmnoncesz@Base 2.5.0 + twofish_gcmtagsz@Base 2.5.0 + twofish_gcmaadinit@Base 2.5.0 + twofish_gcmaadhash@Base 2.5.0 + twofish_gcmencrypt@Base 2.5.0 + twofish_gcmdecrypt@Base 2.5.0 + twofish_gcmencryptdone@Base 2.5.0 + twofish_gcmdecryptdone@Base 2.5.0 + twofish_gcm@Base 2.5.0 + twofish_ocb1init@Base 2.5.0 + twofish_ocb1reinit@Base 2.5.0 + twofish_ocb1setkey@Base 2.5.0 + twofish_ocb1policy@Base 2.5.0 + twofish_ocb1noncesz@Base 2.5.0 + twofish_ocb1tagsz@Base 2.5.0 + twofish_ocb1aadinit@Base 2.5.0 + twofish_ocb1aadhash@Base 2.5.0 + twofish_ocb1aadtag@Base 2.5.0 + twofish_ocb1encrypt@Base 2.5.0 + twofish_ocb1decrypt@Base 2.5.0 + twofish_ocb1encryptdone@Base 2.5.0 + twofish_ocb1decryptdone@Base 2.5.0 + twofish_ocb1@Base 2.5.0 + twofish_ocb3init@Base 2.5.0 + twofish_ocb3step@Base 2.5.0 + twofish_ocb3reinit@Base 2.5.0 + twofish_ocb3setkey@Base 2.5.0 + twofish_ocb3noncesz@Base 2.5.0 + twofish_ocb3aadinit@Base 2.5.0 + twofish_ocb3aadhash@Base 2.5.0 + twofish_ocb3encrypt@Base 2.5.0 + twofish_ocb3decrypt@Base 2.5.0 + twofish_ocb3encryptdone@Base 2.5.0 + twofish_ocb3decryptdone@Base 2.5.0 + twofish_ocb3tagsz@Base 2.5.0 + twofish_ocb3@Base 2.5.0 + twofish_omacmasks@Base 2.5.0 + twofish_omacpolicy@Base 2.5.0 + twofish_omacdone@Base 2.5.0 + twofish_cmacinit@Base 2.5.0 + twofish_cmacsetkey@Base 2.5.0 + twofish_cmachash@Base 2.5.0 + twofish_cmacdone@Base 2.5.0 + twofish_cmac@Base 2.5.0 + twofish_pmac1init@Base 2.5.0 + twofish_pmac1setkey@Base 2.5.0 + twofish_pmac1hash@Base 2.5.0 + twofish_pmac1done@Base 2.5.0 + twofish_pmac1@Base 2.5.0 ## xtea xtea_init@Base 2.0.0 @@ -1774,6 +3453,80 @@ libcatacomb.so.2 catacomb2 #MINVER# xtea_counterbdry@Base 2.0.0 xtea_counter@Base 2.0.0 xtea_counterrand@Base 2.0.0 + xtea_ccminit@Base 2.5.0 + xtea_ccmreinit@Base 2.5.0 + xtea_ccmnoncesz@Base 2.5.0 + xtea_ccmtagsz@Base 2.5.0 + xtea_ccmaadhash@Base 2.5.0 + xtea_ccmencrypt@Base 2.5.0 + xtea_ccmdecrypt@Base 2.5.0 + xtea_ccmencryptdone@Base 2.5.0 + xtea_ccmdecryptdone@Base 2.5.0 + xtea_ccm@Base 2.5.0 + xtea_eaxinit@Base 2.5.0 + xtea_eaxreinit@Base 2.5.0 + xtea_eaxsetkey@Base 2.5.0 + xtea_eaxnoncesz@Base 2.5.0 + xtea_eaxtagsz@Base 2.5.0 + xtea_eaxaadinit@Base 2.5.0 + xtea_eaxaadhash@Base 2.5.0 + xtea_eaxencrypt@Base 2.5.0 + xtea_eaxdecrypt@Base 2.5.0 + xtea_eaxencryptdone@Base 2.5.0 + xtea_eaxdecryptdone@Base 2.5.0 + xtea_eax@Base 2.5.0 + xtea_gcminit@Base 2.5.0 + xtea_gcmreinit@Base 2.5.0 + xtea_gcmsetkey@Base 2.5.0 + xtea_gcmnoncesz@Base 2.5.0 + xtea_gcmtagsz@Base 2.5.0 + xtea_gcmaadinit@Base 2.5.0 + xtea_gcmaadhash@Base 2.5.0 + xtea_gcmencrypt@Base 2.5.0 + xtea_gcmdecrypt@Base 2.5.0 + xtea_gcmencryptdone@Base 2.5.0 + xtea_gcmdecryptdone@Base 2.5.0 + xtea_gcm@Base 2.5.0 + xtea_ocb1init@Base 2.5.0 + xtea_ocb1reinit@Base 2.5.0 + xtea_ocb1setkey@Base 2.5.0 + xtea_ocb1policy@Base 2.5.0 + xtea_ocb1noncesz@Base 2.5.0 + xtea_ocb1tagsz@Base 2.5.0 + xtea_ocb1aadinit@Base 2.5.0 + xtea_ocb1aadhash@Base 2.5.0 + xtea_ocb1aadtag@Base 2.5.0 + xtea_ocb1encrypt@Base 2.5.0 + xtea_ocb1decrypt@Base 2.5.0 + xtea_ocb1encryptdone@Base 2.5.0 + xtea_ocb1decryptdone@Base 2.5.0 + xtea_ocb1@Base 2.5.0 + xtea_ocb3init@Base 2.5.0 + xtea_ocb3step@Base 2.5.0 + xtea_ocb3reinit@Base 2.5.0 + xtea_ocb3setkey@Base 2.5.0 + xtea_ocb3noncesz@Base 2.5.0 + xtea_ocb3aadinit@Base 2.5.0 + xtea_ocb3aadhash@Base 2.5.0 + xtea_ocb3encrypt@Base 2.5.0 + xtea_ocb3decrypt@Base 2.5.0 + xtea_ocb3encryptdone@Base 2.5.0 + xtea_ocb3decryptdone@Base 2.5.0 + xtea_ocb3tagsz@Base 2.5.0 + xtea_ocb3@Base 2.5.0 + xtea_omacmasks@Base 2.5.0 + xtea_omacpolicy@Base 2.5.0 + xtea_omacdone@Base 2.5.0 + xtea_cmacinit@Base 2.5.0 + xtea_cmacsetkey@Base 2.5.0 + xtea_cmachash@Base 2.5.0 + xtea_cmacdone@Base 2.5.0 + xtea_cmac@Base 2.5.0 + xtea_pmac1init@Base 2.5.0 + xtea_pmac1setkey@Base 2.5.0 + xtea_pmac1hash@Base 2.5.0 + xtea_pmac1done@Base 2.5.0 + xtea_pmac1@Base 2.5.0 ## gcrc32 gcrc32@Base 2.1.0 diff --git a/debian/changelog b/debian/changelog index 8ac80a43..066dcc59 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,28 @@ +catacomb (2.5.1) experimental; urgency=medium + + * Merge changes from 2.4.4. + + -- Mark Wooding Sun, 29 Sep 2019 17:50:59 +0100 + +catacomb (2.5.0) experimental; urgency=medium + + * catacomb: MACs based on blockciphers: PMAC1 and CMAC (also known as + OMAC). + * catacomb: Authenticated Encryption with Additional Data (AEAD) + schemes. Some based on blockciphers: CCM, EAX, GCM (with CPU-specific + acceleration), OCB1 and OCB3 (OCB2 is broken). Also Salsa20 and + ChaCha20 with Poly1305: the RFC7539 scheme, and the NaCl `secret_box' + transform. + * catacomb: Implement Grantham's Frobenius test. Combine it with + Rabin--Miller, as Baillie--PSW, for testing given primes. + * catacomb-bin (catcrypt): Support AEAD schemes for bulk crypto. + * catacomb-bin (perftest): Options for batching; report cycle counts + where available. + * Many internal improvements: better documentation, debugging, testing, + etc. + + -- Mark Wooding Sat, 21 Sep 2019 21:26:44 +0100 + catacomb (2.4.4) experimental; urgency=medium * debian: Bump to Debhelper 10. diff --git a/debian/control b/debian/control index be186cfd..c22c2559 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: catacomb Section: libs Priority: extra Build-Depends: debhelper (>= 10), python, valgrind [!armel], pkg-config, - mlib-dev (>= 2.2.2.1) + mlib-dev (>= 2.3.0) Maintainer: Mark Wooding Standards-Version: 3.1.1 diff --git a/math/Makefile.am b/math/Makefile.am index ac654d91..dd48057a 100644 --- a/math/Makefile.am +++ b/math/Makefile.am @@ -245,9 +245,10 @@ libmath_la_SOURCES += pfilt.c pkginclude_HEADERS += pgen.h libmath_la_SOURCES += pgen.c libmath_la_SOURCES += pgen-gcd.c +libmath_la_SOURCES += pgen-granfrob.c libmath_la_SOURCES += pgen-simul.c libmath_la_SOURCES += pgen-stdev.c -TESTS += pgen.t$(EXEEXT) +TESTS += pgen.t$(EXEEXT) pgen-granfrob.t$(EXEEXT) EXTRA_DIST += t/pgen ## Finding primitive elements in finite fields. diff --git a/math/f25519.c b/math/f25519.c index 78844be6..a886465e 100644 --- a/math/f25519.c +++ b/math/f25519.c @@ -50,7 +50,6 @@ typedef uint32 upiece; typedef uint64 udblpiece; #define M26 0x03ffffffu #define M25 0x01ffffffu -#define B26 0x04000000u #define B25 0x02000000u #define B24 0x01000000u @@ -83,11 +82,10 @@ typedef uint16 upiece; typedef uint32 udblpiece; ((i) == 5 || (i) == 10 || (i) == 15 || (i) == 20 || (i) == 25 ? 9 : 10) #define NPIECE 26 -#define B10 0x0400 -#define B9 0x200 -#define B8 0x100 #define M10 0x3ff #define M9 0x1ff +#define B9 0x200 +#define B8 0x100 #endif diff --git a/math/fgoldi.c b/math/fgoldi.c index 9061a74e..1b09b58e 100644 --- a/math/fgoldi.c +++ b/math/fgoldi.c @@ -51,10 +51,8 @@ typedef uint32 upiece; typedef uint64 udblpiece; #define NPIECE 16 #define P p28 -#define B28 0x10000000u #define B27 0x08000000u #define M28 0x0fffffffu -#define M27 0x07ffffffu #define M32 0xffffffffu #elif FGOLDI_IMPL == 12 @@ -70,12 +68,10 @@ typedef uint16 upiece; typedef uint32 udblpiece; #define NPIECE 40 #define P p12 -#define B12 0x1000u #define B11 0x0800u #define B10 0x0400u #define M12 0xfffu #define M11 0x7ffu -#define M10 0x3ffu #define M8 0xffu #endif diff --git a/math/mp-sqrt.c b/math/mp-sqrt.c index 2dbe4189..bf19fe8e 100644 --- a/math/mp-sqrt.c +++ b/math/mp-sqrt.c @@ -71,12 +71,32 @@ mp *mp_sqrt(mp *d, mp *a) /* --- Main approximation --- * * - * We use the Newton-Raphson recurrence relation + * The Newton--Raphson method finds approximate zeroes of a function by + * starting with a guess and repeatedly refining the guess by approximating + * the function near the guess by its tangent at the guess + * %$x$%-coordinate, using where the tangent cuts the %$x$%-axis as the new + * guess. * - * %$x_{i+1} = x_i - \frac{x_i^2 - a}{2 x_i}$% + * Given a function %$f(x)$% and a guess %$x_i$%, the tangent has the + * equation %$y = f(x_i) + f'(x_i) (x - x_i)$%, which is zero when * - * We inspect the term %$q = x^2 - a$% to see when to stop. Increasing - * %$x$% is pointless when %$-q < 2 x + 1$%. + * %$\displaystyle x = x_i - \frac{f(x_i)}{f'(x_i)} + * + * We set %$f(x) = x^2 - a$%, so our recurrence will be + * + * %$\displaystyle x_{i+1} = x_i - \frac{x_i^2 - a}{2 x_i}$% + * + * It's possible to simplify this, but it's useful to see %$q = x_i^2 - a$% + * so that we know when to stop. We want the largest integer not larger + * than the true square root. If %$q > 0$% then %$x_i$% is definitely too + * large, and we should decrease it by at least one even if the adjustment + * term %$(x_i^2 - a)/2 x$% is less than one. + * + * Suppose, then, that %$q \le 0$%. Then %$(x_i + 1)^2 - a = {}$% + * $%x_i^2 + 2 x_i + 1 - a = q + 2 x_i + 1$%. Hence, if %$q \ge -2 x_i$% + * then %$x_i + 1$% is an overestimate and we should settle where we are. + * Otherwise, %$x_i + 1$% is an underestimate -- but, in this case the + * adjustment will always be at least one. */ for (;;) { diff --git a/math/mpmont.c b/math/mpmont.c index f8a26119..094ac401 100644 --- a/math/mpmont.c +++ b/math/mpmont.c @@ -90,19 +90,25 @@ static void simple_redccore(mpw *dv, mpw *dvl, const mpw *mv, #if CPUFAM_X86 MAYBE_REDC4(x86_sse2) + MAYBE_REDC4(x86_avx) #endif #if CPUFAM_AMD64 MAYBE_REDC4(amd64_sse2) + MAYBE_REDC4(amd64_avx) #endif static redccore__functype *pick_redccore(void) { #if CPUFAM_X86 + DISPATCH_PICK_COND(mpmont_reduce, maybe_redc4_x86_avx, + cpu_feature_p(CPUFEAT_X86_AVX)); DISPATCH_PICK_COND(mpmont_reduce, maybe_redc4_x86_sse2, cpu_feature_p(CPUFEAT_X86_SSE2)); #endif #if CPUFAM_AMD64 + DISPATCH_PICK_COND(mpmont_reduce, maybe_redc4_amd64_avx, + cpu_feature_p(CPUFEAT_X86_AVX)); DISPATCH_PICK_COND(mpmont_reduce, maybe_redc4_amd64_sse2, cpu_feature_p(CPUFEAT_X86_SSE2)); #endif @@ -190,19 +196,25 @@ static void simple_mulcore(mpw *dv, mpw *dvl, #if CPUFAM_X86 MAYBE_MUL4(x86_sse2) + MAYBE_MUL4(x86_avx) #endif #if CPUFAM_AMD64 MAYBE_MUL4(amd64_sse2) + MAYBE_MUL4(amd64_avx) #endif static mulcore__functype *pick_mulcore(void) { #if CPUFAM_X86 + DISPATCH_PICK_COND(mpmont_mul, maybe_mul4_x86_avx, + cpu_feature_p(CPUFEAT_X86_AVX)); DISPATCH_PICK_COND(mpmont_mul, maybe_mul4_x86_sse2, cpu_feature_p(CPUFEAT_X86_SSE2)); #endif #if CPUFAM_AMD64 + DISPATCH_PICK_COND(mpmont_mul, maybe_mul4_amd64_avx, + cpu_feature_p(CPUFEAT_X86_AVX)); DISPATCH_PICK_COND(mpmont_mul, maybe_mul4_amd64_sse2, cpu_feature_p(CPUFEAT_X86_SSE2)); #endif diff --git a/math/mpx-mul4-amd64-sse2.S b/math/mpx-mul4-amd64-sse2.S index 9146a63f..03e466c7 100644 --- a/math/mpx-mul4-amd64-sse2.S +++ b/math/mpx-mul4-amd64-sse2.S @@ -25,15 +25,13 @@ /// MA 02111-1307, USA. ///-------------------------------------------------------------------------- -/// External definitions. +/// Preliminaries. #include "config.h" #include "asm-common.h" -///-------------------------------------------------------------------------- -/// Prologue. - .arch pentium4 + .text ///-------------------------------------------------------------------------- @@ -96,32 +94,32 @@ .macro mulcore r, i, slo, shi, d0, d1=nil, d2=nil, d3=nil // Multiply R_I by the expanded operand SLO/SHI, and leave the pieces // of the product in registers D0, D1, D2, D3. - pshufd \d0, \r, SHUF(3, \i, 3, \i) // (r_i, ?, r_i, ?) + pshufd \d0, \r, SHUF(\i, 3, \i, 3) // (r_i, ?; r_i, ?) .ifnes "\d1", "nil" - movdqa \d1, \slo // (s'_0, s'_1, s''_0, s''_1) + movdqa \d1, \slo // (s'_0, s'_1; s''_0, s''_1) .endif .ifnes "\d3", "nil" - movdqa \d3, \shi // (s'_2, s'_3, s''_2, s''_3) + movdqa \d3, \shi // (s'_2, s'_3; s''_2, s''_3) .endif .ifnes "\d1", "nil" - psrldq \d1, 4 // (s'_1, s''_0, s''_1, 0) + psrldq \d1, 4 // (s'_1, s''_0; s''_1, 0) .endif .ifnes "\d2", "nil" - movdqa \d2, \d0 // another copy of (r_i, ?, r_i, ?) + movdqa \d2, \d0 // another copy of (r_i, ?; r_i, ?) .endif .ifnes "\d3", "nil" - psrldq \d3, 4 // (s'_3, s''_2, s''_3, 0) + psrldq \d3, 4 // (s'_3, s''_2; s''_3, 0) .endif .ifnes "\d1", "nil" - pmuludq \d1, \d0 // (r_i s'_1, r_i s''_1) + pmuludq \d1, \d0 // (r_i s'_1; r_i s''_1) .endif .ifnes "\d3", "nil" - pmuludq \d3, \d0 // (r_i s'_3, r_i s''_3) + pmuludq \d3, \d0 // (r_i s'_3; r_i s''_3) .endif .ifnes "\d2", "nil" - pmuludq \d2, \shi // (r_i s'_2, r_i s''_2) + pmuludq \d2, \shi // (r_i s'_2; r_i s''_2) .endif - pmuludq \d0, \slo // (r_i s'_0, r_i s''_0) + pmuludq \d0, \slo // (r_i s'_0; r_i s''_0) .endm .macro accum c0, c1=nil, c2=nil, c3=nil @@ -163,10 +161,10 @@ // lane 0 or 1 of D; the high two lanes of D are clobbered. On // completion, XMM3 is clobbered. If CC is `nil', then the // contribution which would have been added to it is left in C. - pshufd xmm3, \c, SHUF(2, 3, 3, 3) // (?, ?, ?, t = c'' mod B) - psrldq xmm3, 12 // (t, 0, 0, 0) = (t, 0) - pslldq xmm3, 2 // (t b, 0) - paddq \c, xmm3 // (c' + t b, c'') + pshufd xmm3, \c, SHUF(3, 3, 3, 2) // (?, ?; ?, t = c'' mod B) + psrldq xmm3, 12 // (t, 0; 0, 0) = (t; 0) + pslldq xmm3, 2 // (t b; 0) + paddq \c, xmm3 // (c' + t b; c'') .ifeqs "\pos", "lo" movdqa \d, \c .else @@ -183,37 +181,37 @@ // of the value represented in C are written at POS in D, and the // remaining bits are left at the bottom of T. movdqa \t, \c - psllq \t, 16 // (?, c'' b) - pslldq \c, 8 // (0, c') - paddq \t, \c // (?, c' + c'' b) - psrldq \t, 8 // c' + c'' b + psllq \t, 16 // (?; c'' b) + pslldq \c, 8 // (0; c') + paddq \t, \c // (?; c' + c'' b) + psrldq \t, 8 // (c' + c'' b; 0) = (c; 0) .ifeqs "\pos", "lo" movdqa \d, \t .else punpckldq \d, \t .endif - psrldq \t, 4 // floor((c' + c'' b)/B) + psrldq \t, 4 // (floor(c/B); 0) .endm .macro expand z, a, b, c=nil, d=nil // On entry, A and C hold packed 128-bit values, and Z is zero. On // exit, A:B and C:D together hold the same values in expanded // form. If C is `nil', then only expand A to A:B. - movdqa \b, \a // (a_0, a_1, a_2, a_3) + movdqa \b, \a // (a_0, a_1; a_2, a_3) .ifnes "\c", "nil" - movdqa \d, \c // (c_0, c_1, c_2, c_3) + movdqa \d, \c // (c_0, c_1; c_2, c_3) .endif - punpcklwd \a, \z // (a'_0, a''_0, a'_1, a''_1) - punpckhwd \b, \z // (a'_2, a''_2, a'_3, a''_3) + punpcklwd \a, \z // (a'_0, a''_0; a'_1, a''_1) + punpckhwd \b, \z // (a'_2, a''_2; a'_3, a''_3) .ifnes "\c", "nil" - punpcklwd \c, \z // (c'_0, c''_0, c'_1, c''_1) - punpckhwd \d, \z // (c'_2, c''_2, c'_3, c''_3) + punpcklwd \c, \z // (c'_0, c''_0; c'_1, c''_1) + punpckhwd \d, \z // (c'_2, c''_2; c'_3, c''_3) .endif - pshufd \a, \a, SHUF(3, 1, 2, 0) // (a'_0, a'_1, a''_0, a''_1) - pshufd \b, \b, SHUF(3, 1, 2, 0) // (a'_2, a'_3, a''_2, a''_3) + pshufd \a, \a, SHUF(0, 2, 1, 3) // (a'_0, a'_1; a''_0, a''_1) + pshufd \b, \b, SHUF(0, 2, 1, 3) // (a'_2, a'_3; a''_2, a''_3) .ifnes "\c", "nil" - pshufd \c, \c, SHUF(3, 1, 2, 0) // (c'_0, c'_1, c''_0, c''_1) - pshufd \d, \d, SHUF(3, 1, 2, 0) // (c'_2, c'_3, c''_2, c''_3) + pshufd \c, \c, SHUF(0, 2, 1, 3) // (c'_0, c'_1; c''_0, c''_1) + pshufd \d, \d, SHUF(0, 2, 1, 3) // (c'_2, c'_3; c''_2, c''_3) .endif .endm @@ -229,10 +227,10 @@ // we can do that, we must gather them together. movdqa \t, \c0 movdqa \u, \c1 - punpcklqdq \t, \c2 // (y'_0, y'_2) - punpckhqdq \c0, \c2 // (y''_0, y''_2) - punpcklqdq \u, \c3 // (y'_1, y'_3) - punpckhqdq \c1, \c3 // (y''_1, y''_3) + punpcklqdq \t, \c2 // (y'_0; y'_2) + punpckhqdq \c0, \c2 // (y''_0; y''_2) + punpcklqdq \u, \c3 // (y'_1; y'_3) + punpckhqdq \c1, \c3 // (y''_1; y''_3) // Now split the double-prime pieces. The high (up to) 48 bits will // go up; the low 16 bits go down. @@ -240,43 +238,43 @@ movdqa \c3, \c1 psllq \c2, 48 psllq \c3, 48 - psrlq \c0, 16 // high parts of (y''_0, y''_2) - psrlq \c1, 16 // high parts of (y''_1, y''_3) - psrlq \c2, 32 // low parts of (y''_0, y''_2) - psrlq \c3, 32 // low parts of (y''_1, y''_3) + psrlq \c0, 16 // high parts of (y''_0; y''_2) + psrlq \c1, 16 // high parts of (y''_1; y''_3) + psrlq \c2, 32 // low parts of (y''_0; y''_2) + psrlq \c3, 32 // low parts of (y''_1; y''_3) .ifnes "\hi", "nil" movdqa \hi, \c1 .endif - pslldq \c1, 8 // high part of (0, y''_1) + pslldq \c1, 8 // high part of (0; y''_1) paddq \t, \c2 // propagate down paddq \u, \c3 - paddq \t, \c1 // and up: (y_0, y_2) - paddq \u, \c0 // (y_1, y_3) + paddq \t, \c1 // and up: (y_0; y_2) + paddq \u, \c0 // (y_1; y_3) .ifnes "\hi", "nil" - psrldq \hi, 8 // high part of (y''_3, 0) + psrldq \hi, 8 // high part of (y''_3; 0) .endif // Finally extract the answer. This complicated dance is better than // storing to memory and loading, because the piecemeal stores // inhibit store forwarding. - movdqa \c3, \t // (y_0, y_1) - movdqa \lo, \t // (y^*_0, ?, ?, ?) - psrldq \t, 8 // (y_2, 0) - psrlq \c3, 32 // (floor(y_0/B), ?) - paddq \c3, \u // (y_1 + floor(y_0/B), ?) - movdqa \c1, \c3 // (y^*_1, ?, ?, ?) - psrldq \u, 8 // (y_3, 0) - psrlq \c3, 32 // (floor((y_1 B + y_0)/B^2, ?) - paddq \c3, \t // (y_2 + floor((y_1 B + y_0)/B^2, ?) - punpckldq \lo, \c3 // (y^*_0, y^*_2, ?, ?) - psrlq \c3, 32 // (floor((y_2 B^2 + y_1 B + y_0)/B^3, ?) - paddq \c3, \u // (y_3 + floor((y_2 B^2 + y_1 B + y_0)/B^3, ?) + movdqa \c3, \t // (y_0; ?) + movdqa \lo, \t // (y^*_0, ?; ?, ?) + psrldq \t, 8 // (y_2; 0) + psrlq \c3, 32 // (floor(y_0/B); ?) + paddq \c3, \u // (y_1 + floor(y_0/B); ?) + movdqa \c1, \c3 // (y^*_1, ?; ?, ?) + psrldq \u, 8 // (y_3; 0) + psrlq \c3, 32 // (floor((y_1 B + y_0)/B^2; ?) + paddq \c3, \t // (y_2 + floor((y_1 B + y_0)/B^2; ?) + punpckldq \lo, \c3 // (y^*_0, y^*_2; ?, ?) + psrlq \c3, 32 // (floor((y_2 B^2 + y_1 B + y_0)/B^3; ?) + paddq \c3, \u // (y_3 + floor((y_2 B^2 + y_1 B + y_0)/B^3; ?) .ifnes "\hi", "nil" movdqa \t, \c3 pxor \u, \u .endif - punpckldq \c1, \c3 // (y^*_1, y^*_3, ?, ?) + punpckldq \c1, \c3 // (y^*_1, y^*_3; ?, ?) .ifnes "\hi", "nil" psrlq \t, 32 // very high bits of y paddq \hi, \t @@ -293,13 +291,13 @@ // On exit, the carry registers, including XMM15, are updated to hold // C + A; XMM0, XMM1, XMM2, and XMM3 are clobbered. The other // registers are preserved. - movd xmm0, [rdi + 0] // (a_0, 0) - movd xmm1, [rdi + 4] // (a_1, 0) - movd xmm2, [rdi + 8] // (a_2, 0) - movd xmm15, [rdi + 12] // (a_3, 0) - paddq xmm12, xmm0 // (c'_0 + a_0, c''_0) - paddq xmm13, xmm1 // (c'_1 + a_1, c''_1) - paddq xmm14, xmm2 // (c'_2 + a_2, c''_2 + a_3 b) + movd xmm0, [rdi + 0] // (a_0; 0) + movd xmm1, [rdi + 4] // (a_1; 0) + movd xmm2, [rdi + 8] // (a_2; 0) + movd xmm15, [rdi + 12] // (a_3; 0) + paddq xmm12, xmm0 // (c'_0 + a_0; c''_0) + paddq xmm13, xmm1 // (c'_1 + a_1; c''_1) + paddq xmm14, xmm2 // (c'_2 + a_2; c''_2 + a_3 b) .endm ///-------------------------------------------------------------------------- @@ -621,8 +619,8 @@ INTFUNC(mmla4) mulcore xmm7, 1, xmm10, xmm11, xmm0, xmm1, xmm2 accum xmm4, xmm5, xmm6 - punpckldq xmm12, xmm15 // (w_0, 0, w_1, 0) - punpckhdq xmm14, xmm15 // (w_2, 0, w_3, 0) + punpckldq xmm12, xmm15 // (w_0, 0; w_1, 0) + punpckhdq xmm14, xmm15 // (w_2, 0; w_3, 0) mulcore xmm7, 2, xmm10, xmm11, xmm0, xmm1 accum xmm5, xmm6 @@ -634,10 +632,10 @@ INTFUNC(mmla4) mulcore xmm7, 3, xmm10, xmm11, xmm0 accum xmm6 - punpckldq xmm12, xmm2 // (w_0, 0, 0, 0) - punpckldq xmm14, xmm2 // (w_2, 0, 0, 0) - punpckhdq xmm13, xmm2 // (w_1, 0, 0, 0) - punpckhdq xmm15, xmm2 // (w_3, 0, 0, 0) + punpckldq xmm12, xmm2 // (w_0, 0; 0, 0) + punpckldq xmm14, xmm2 // (w_2, 0; 0, 0) + punpckhdq xmm13, xmm2 // (w_1, 0; 0, 0) + punpckhdq xmm15, xmm2 // (w_3, 0; 0, 0) // That's lots of pieces. Now we have to assemble the answer. squash xmm3, xmm4, xmm5, xmm6, xmm0, xmm1, xmm10 @@ -703,8 +701,8 @@ INTFUNC(mont4) mulcore xmm7, 1, xmm8, xmm9, xmm0, xmm1, xmm2 accum xmm4, xmm5, xmm6 - punpckldq xmm12, xmm15 // (w_0, 0, w_1, 0) - punpckhdq xmm14, xmm15 // (w_2, 0, w_3, 0) + punpckldq xmm12, xmm15 // (w_0, 0; w_1, 0) + punpckhdq xmm14, xmm15 // (w_2, 0; w_3, 0) mulcore xmm7, 2, xmm8, xmm9, xmm0, xmm1 accum xmm5, xmm6 @@ -716,10 +714,10 @@ INTFUNC(mont4) mulcore xmm7, 3, xmm8, xmm9, xmm0 accum xmm6 - punpckldq xmm12, xmm2 // (w_0, 0, 0, 0) - punpckldq xmm14, xmm2 // (w_2, 0, 0, 0) - punpckhdq xmm13, xmm2 // (w_1, 0, 0, 0) - punpckhdq xmm15, xmm2 // (w_3, 0, 0, 0) + punpckldq xmm12, xmm2 // (w_0, 0; 0, 0) + punpckldq xmm14, xmm2 // (w_2, 0; 0, 0) + punpckhdq xmm13, xmm2 // (w_1, 0; 0, 0) + punpckhdq xmm15, xmm2 // (w_3, 0; 0, 0) // That's lots of pieces. Now we have to assemble the answer. squash xmm3, xmm4, xmm5, xmm6, xmm0, xmm1, xmm10 @@ -752,6 +750,13 @@ ENDFUNC ///-------------------------------------------------------------------------- /// Bulk multipliers. +FUNC(mpx_umul4_amd64_avx) + .arch .avx + vzeroupper + endprologue + .arch pentium4 +ENDFUNC + FUNC(mpx_umul4_amd64_sse2) // void mpx_umul4_amd64_sse2(mpw *dv, const mpw *av, const mpw *avl, // const mpw *bv, const mpw *bvl); @@ -901,6 +906,13 @@ FUNC(mpx_umul4_amd64_sse2) ENDFUNC +FUNC(mpxmont_mul4_amd64_avx) + .arch .avx + vzeroupper + endprologue + .arch pentium4 +ENDFUNC + FUNC(mpxmont_mul4_amd64_sse2) // void mpxmont_mul4_amd64_sse2(mpw *dv, const mpw *av, const mpw *bv, // const mpw *nv, size_t n, const mpw *mi); @@ -1095,6 +1107,13 @@ FUNC(mpxmont_mul4_amd64_sse2) ENDFUNC +FUNC(mpxmont_redc4_amd64_avx) + .arch .avx + vzeroupper + endprologue + .arch pentium4 +ENDFUNC + FUNC(mpxmont_redc4_amd64_sse2) // void mpxmont_redc4_amd64_sse2(mpw *dv, mpw *dvl, const mpw *nv, // size_t n, const mpw *mi); @@ -1474,9 +1493,9 @@ ENDFUNC .endm .macro testldcarry - movdqu xmm12, [rcx + 0] // (c'_0, c''_0) - movdqu xmm13, [rcx + 16] // (c'_1, c''_1) - movdqu xmm14, [rcx + 32] // (c'_2, c''_2) + movdqu xmm12, [rcx + 0] // (c'_0; c''_0) + movdqu xmm13, [rcx + 16] // (c'_1; c''_1) + movdqu xmm14, [rcx + 32] // (c'_2; c''_2) .endm .macro testtop u=nil diff --git a/math/mpx-mul4-x86-sse2.S b/math/mpx-mul4-x86-sse2.S index f6c81673..9d664b44 100644 --- a/math/mpx-mul4-x86-sse2.S +++ b/math/mpx-mul4-x86-sse2.S @@ -24,15 +24,13 @@ /// MA 02111-1307, USA. ///-------------------------------------------------------------------------- -/// External definitions. +/// Preliminaries. #include "config.h" #include "asm-common.h" -///-------------------------------------------------------------------------- -/// Prologue. - .arch pentium4 + .text ///-------------------------------------------------------------------------- @@ -96,41 +94,41 @@ .macro mulcore r, s, d0, d1=nil, d2=nil, d3=nil // Load a word r_i from R, multiply by the expanded operand [S], and // leave the pieces of the product in registers D0, D1, D2, D3. - movd \d0, \r // (r_i, 0, 0, 0) + movd \d0, \r // (r_i, 0; 0, 0) .ifnes "\d1", "nil" - movdqa \d1, [\s] // (s'_0, s'_1, s''_0, s''_1) + movdqa \d1, [\s] // (s'_0, s'_1; s''_0, s''_1) .endif .ifnes "\d3", "nil" - movdqa \d3, [\s + 16] // (s'_2, s'_3, s''_2, s''_3) + movdqa \d3, [\s + 16] // (s'_2, s'_3; s''_2, s''_3) .endif - pshufd \d0, \d0, SHUF(3, 0, 3, 0) // (r_i, ?, r_i, ?) + pshufd \d0, \d0, SHUF(0, 3, 0, 3) // (r_i, ?; r_i, ?) .ifnes "\d1", "nil" - psrldq \d1, 4 // (s'_1, s''_0, s''_1, 0) + psrldq \d1, 4 // (s'_1, s''_0; s''_1, 0) .endif .ifnes "\d2", "nil" .ifnes "\d3", "nil" - movdqa \d2, \d3 // another copy of (s'_2, s'_3, ...) + movdqa \d2, \d3 // another copy of (s'_2, s'_3; ...) .else - movdqa \d2, \d0 // another copy of (r_i, ?, r_i, ?) + movdqa \d2, \d0 // another copy of (r_i, ?; r_i, ?) .endif .endif .ifnes "\d3", "nil" - psrldq \d3, 4 // (s'_3, s''_2, s''_3, 0) + psrldq \d3, 4 // (s'_3, s''_2; s''_3, 0) .endif .ifnes "\d1", "nil" - pmuludq \d1, \d0 // (r_i s'_1, r_i s''_1) + pmuludq \d1, \d0 // (r_i s'_1; r_i s''_1) .endif .ifnes "\d3", "nil" - pmuludq \d3, \d0 // (r_i s'_3, r_i s''_3) + pmuludq \d3, \d0 // (r_i s'_3; r_i s''_3) .endif .ifnes "\d2", "nil" .ifnes "\d3", "nil" - pmuludq \d2, \d0 // (r_i s'_2, r_i s''_2) + pmuludq \d2, \d0 // (r_i s'_2; r_i s''_2) .else pmuludq \d2, [\s + 16] .endif .endif - pmuludq \d0, [\s] // (r_i s'_0, r_i s''_0) + pmuludq \d0, [\s] // (r_i s'_0; r_i s''_0) .endm .macro accum c0, c1=nil, c2=nil, c3=nil @@ -171,10 +169,10 @@ // carry registers. On completion, XMM3 is clobbered. If CC is // `nil', then the contribution which would have been added to it is // left in C. - pshufd xmm3, \c, SHUF(2, 3, 3, 3) // (?, ?, ?, t = c'' mod B) - psrldq xmm3, 12 // (t, 0, 0, 0) = (t, 0) - pslldq xmm3, 2 // (t b, 0) - paddq \c, xmm3 // (c' + t b, c'') + pshufd xmm3, \c, SHUF(3, 3, 3, 2) // (?, ?; ?, t = c'' mod B) + psrldq xmm3, 12 // (t, 0; 0, 0) = (t, 0) + pslldq xmm3, 2 // (t b; 0) + paddq \c, xmm3 // (c' + t b; c'') movd \d, \c psrlq \c, 32 // floor(c/B) .ifnes "\cc", "nil" @@ -187,33 +185,33 @@ // of the value represented in C are written to D, and the remaining // bits are left at the bottom of T. movdqa \t, \c - psllq \t, 16 // (?, c'' b) - pslldq \c, 8 // (0, c') - paddq \t, \c // (?, c' + c'' b) - psrldq \t, 8 // c' + c'' b + psllq \t, 16 // (?; c'' b) + pslldq \c, 8 // (0; c') + paddq \t, \c // (?; c' + c'' b) + psrldq \t, 8 // (c' + c'' b; 0) = (c; 0) movd \d, \t - psrldq \t, 4 // floor((c' + c'' b)/B) + psrldq \t, 4 // (floor(c/B); 0) .endm .macro expand z, a, b, c=nil, d=nil // On entry, A and C hold packed 128-bit values, and Z is zero. On // exit, A:B and C:D together hold the same values in expanded // form. If C is `nil', then only expand A to A:B. - movdqa \b, \a // (a_0, a_1, a_2, a_3) + movdqa \b, \a // (a_0, a_1; a_2, a_3) .ifnes "\c", "nil" - movdqa \d, \c // (c_0, c_1, c_2, c_3) + movdqa \d, \c // (c_0, c_1; c_2, c_3) .endif - punpcklwd \a, \z // (a'_0, a''_0, a'_1, a''_1) - punpckhwd \b, \z // (a'_2, a''_2, a'_3, a''_3) + punpcklwd \a, \z // (a'_0, a''_0; a'_1, a''_1) + punpckhwd \b, \z // (a'_2, a''_2; a'_3, a''_3) .ifnes "\c", "nil" - punpcklwd \c, \z // (c'_0, c''_0, c'_1, c''_1) - punpckhwd \d, \z // (c'_2, c''_2, c'_3, c''_3) + punpcklwd \c, \z // (c'_0, c''_0; c'_1, c''_1) + punpckhwd \d, \z // (c'_2, c''_2; c'_3, c''_3) .endif - pshufd \a, \a, SHUF(3, 1, 2, 0) // (a'_0, a'_1, a''_0, a''_1) - pshufd \b, \b, SHUF(3, 1, 2, 0) // (a'_2, a'_3, a''_2, a''_3) + pshufd \a, \a, SHUF(0, 2, 1, 3) // (a'_0, a'_1; a''_0, a''_1) + pshufd \b, \b, SHUF(0, 2, 1, 3) // (a'_2, a'_3; a''_2, a''_3) .ifnes "\c", "nil" - pshufd \c, \c, SHUF(3, 1, 2, 0) // (c'_0, c'_1, c''_0, c''_1) - pshufd \d, \d, SHUF(3, 1, 2, 0) // (c'_2, c'_3, c''_2, c''_3) + pshufd \c, \c, SHUF(0, 2, 1, 3) // (c'_0, c'_1; c''_0, c''_1) + pshufd \d, \d, SHUF(0, 2, 1, 3) // (c'_2, c'_3; c''_2, c''_3) .endif .endm @@ -229,10 +227,10 @@ // we can do that, we must gather them together. movdqa \t, \c0 movdqa \u, \c1 - punpcklqdq \t, \c2 // (y'_0, y'_2) - punpckhqdq \c0, \c2 // (y''_0, y''_2) - punpcklqdq \u, \c3 // (y'_1, y'_3) - punpckhqdq \c1, \c3 // (y''_1, y''_3) + punpcklqdq \t, \c2 // (y'_0; y'_2) + punpckhqdq \c0, \c2 // (y''_0; y''_2) + punpcklqdq \u, \c3 // (y'_1; y'_3) + punpckhqdq \c1, \c3 // (y''_1; y''_3) // Now split the double-prime pieces. The high (up to) 48 bits will // go up; the low 16 bits go down. @@ -240,43 +238,43 @@ movdqa \c3, \c1 psllq \c2, 48 psllq \c3, 48 - psrlq \c0, 16 // high parts of (y''_0, y''_2) - psrlq \c1, 16 // high parts of (y''_1, y''_3) - psrlq \c2, 32 // low parts of (y''_0, y''_2) - psrlq \c3, 32 // low parts of (y''_1, y''_3) + psrlq \c0, 16 // high parts of (y''_0; y''_2) + psrlq \c1, 16 // high parts of (y''_1; y''_3) + psrlq \c2, 32 // low parts of (y''_0; y''_2) + psrlq \c3, 32 // low parts of (y''_1; y''_3) .ifnes "\hi", "nil" movdqa \hi, \c1 .endif - pslldq \c1, 8 // high part of (0, y''_1) + pslldq \c1, 8 // high part of (0; y''_1) paddq \t, \c2 // propagate down paddq \u, \c3 - paddq \t, \c1 // and up: (y_0, y_2) - paddq \u, \c0 // (y_1, y_3) + paddq \t, \c1 // and up: (y_0; y_2) + paddq \u, \c0 // (y_1; y_3) .ifnes "\hi", "nil" - psrldq \hi, 8 // high part of (y''_3, 0) + psrldq \hi, 8 // high part of (y''_3; 0) .endif // Finally extract the answer. This complicated dance is better than // storing to memory and loading, because the piecemeal stores // inhibit store forwarding. - movdqa \c3, \t // (y_0, y_1) - movdqa \lo, \t // (y^*_0, ?, ?, ?) - psrldq \t, 8 // (y_2, 0) - psrlq \c3, 32 // (floor(y_0/B), ?) - paddq \c3, \u // (y_1 + floor(y_0/B), ?) - movdqa \c1, \c3 // (y^*_1, ?, ?, ?) - psrldq \u, 8 // (y_3, 0) - psrlq \c3, 32 // (floor((y_1 B + y_0)/B^2, ?) - paddq \c3, \t // (y_2 + floor((y_1 B + y_0)/B^2, ?) - punpckldq \lo, \c3 // (y^*_0, y^*_2, ?, ?) - psrlq \c3, 32 // (floor((y_2 B^2 + y_1 B + y_0)/B^3, ?) - paddq \c3, \u // (y_3 + floor((y_2 B^2 + y_1 B + y_0)/B^3, ?) + movdqa \c3, \t // (y_0; ?) + movdqa \lo, \t // (y^*_0, ?; ?, ?) + psrldq \t, 8 // (y_2; 0) + psrlq \c3, 32 // (floor(y_0/B); ?) + paddq \c3, \u // (y_1 + floor(y_0/B); ?) + movdqa \c1, \c3 // (y^*_1, ?; ?, ?) + psrldq \u, 8 // (y_3; 0) + psrlq \c3, 32 // (floor((y_1 B + y_0)/B^2; ?) + paddq \c3, \t // (y_2 + floor((y_1 B + y_0)/B^2; ?) + punpckldq \lo, \c3 // (y^*_0, y^*_2; ?, ?) + psrlq \c3, 32 // (floor((y_2 B^2 + y_1 B + y_0)/B^3; ?) + paddq \c3, \u // (y_3 + floor((y_2 B^2 + y_1 B + y_0)/B^3; ?) .ifnes "\hi", "nil" movdqa \t, \c3 pxor \u, \u .endif - punpckldq \c1, \c3 // (y^*_1, y^*_3, ?, ?) + punpckldq \c1, \c3 // (y^*_1, y^*_3; ?, ?) .ifnes "\hi", "nil" psrlq \t, 32 // very high bits of y paddq \hi, \t @@ -293,14 +291,14 @@ // On exit, the carry registers, including XMM7, are updated to hold // C + A; XMM0, XMM1, XMM2, and XMM3 are clobbered. The other // registers are preserved. - movd xmm0, [edi + 0] // (a_0, 0) - movd xmm1, [edi + 4] // (a_1, 0) - movd xmm2, [edi + 8] // (a_2, 0) - movd xmm7, [edi + 12] // (a_3, 0) - - paddq xmm4, xmm0 // (c'_0 + a_0, c''_0) - paddq xmm5, xmm1 // (c'_1 + a_1, c''_1) - paddq xmm6, xmm2 // (c'_2 + a_2, c''_2 + a_3 b) + movd xmm0, [edi + 0] // (a_0; 0) + movd xmm1, [edi + 4] // (a_1; 0) + movd xmm2, [edi + 8] // (a_2; 0) + movd xmm7, [edi + 12] // (a_3; 0) + + paddq xmm4, xmm0 // (c'_0 + a_0; c''_0) + paddq xmm5, xmm1 // (c'_1 + a_1; c''_1) + paddq xmm6, xmm2 // (c'_2 + a_2; c''_2 + a_3 b) .endm ///-------------------------------------------------------------------------- @@ -678,6 +676,14 @@ ENDFUNC ///-------------------------------------------------------------------------- /// Bulk multipliers. +FUNC(mpx_umul4_x86_avx) + .arch .avx + vzeroupper + endprologue + // and drop through... + .arch pentium4 +ENDFUNC + FUNC(mpx_umul4_x86_sse2) // void mpx_umul4_x86_sse2(mpw *dv, const mpw *av, const mpw *avl, // const mpw *bv, const mpw *bvl); @@ -699,7 +705,7 @@ FUNC(mpx_umul4_x86_sse2) pushreg ebx pushreg esi pushreg edi - setfp ebp + setfp and esp, ~15 sub esp, 32 endprologue @@ -778,6 +784,14 @@ FUNC(mpx_umul4_x86_sse2) ENDFUNC +FUNC(mpxmont_mul4_x86_avx) + .arch .avx + vzeroupper + endprologue + // and drop through... + .arch pentium4 +ENDFUNC + FUNC(mpxmont_mul4_x86_sse2) // void mpxmont_mul4_x86_sse2(mpw *dv, const mpw *av, const mpw *bv, // const mpw *nv, size_t n, const mpw *mi); @@ -806,7 +820,7 @@ FUNC(mpxmont_mul4_x86_sse2) pushreg ebx pushreg esi pushreg edi - setfp ebp + setfp and esp, ~15 sub esp, 112 endprologue @@ -919,6 +933,14 @@ FUNC(mpxmont_mul4_x86_sse2) ENDFUNC +FUNC(mpxmont_redc4_x86_avx) + .arch .avx + vzeroupper + endprologue + // and drop through... + .arch pentium4 +ENDFUNC + FUNC(mpxmont_redc4_x86_sse2) // void mpxmont_redc4_x86_sse2(mpw *dv, mpw *dvl, const mpw *nv, // size_t n, const mpw *mi); @@ -944,7 +966,7 @@ FUNC(mpxmont_redc4_x86_sse2) pushreg ebx pushreg esi pushreg edi - setfp ebp + setfp and esp, ~15 sub esp, 76 endprologue @@ -1073,7 +1095,7 @@ ENDFUNC pushreg ebx pushreg esi pushreg edi - setfp ebp + setfp and esp, ~15 sub esp, 3*32 + 4*4 endprologue @@ -1098,9 +1120,9 @@ ENDFUNC .macro testldcarry c mov ecx, \c // -> c - movdqu xmm4, [ecx + 0] // (c'_0, c''_0) - movdqu xmm5, [ecx + 16] // (c'_1, c''_1) - movdqu xmm6, [ecx + 32] // (c'_2, c''_2) + movdqu xmm4, [ecx + 0] // (c'_0; c''_0) + movdqu xmm5, [ecx + 16] // (c'_1; c''_1) + movdqu xmm6, [ecx + 32] // (c'_2; c''_2) .endm .macro testexpand v=nil, y=nil diff --git a/math/mpx.c b/math/mpx.c index 3983e7ca..42948457 100644 --- a/math/mpx.c +++ b/math/mpx.c @@ -923,19 +923,25 @@ static void simple_umul(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl, #if CPUFAM_X86 MAYBE_UMUL4(x86_sse2) + MAYBE_UMUL4(x86_avx) #endif #if CPUFAM_AMD64 MAYBE_UMUL4(amd64_sse2) + MAYBE_UMUL4(amd64_avx) #endif static mpx_umul__functype *pick_umul(void) { #if CPUFAM_X86 + DISPATCH_PICK_COND(mpx_umul, maybe_umul4_x86_avx, + cpu_feature_p(CPUFEAT_X86_AVX)); DISPATCH_PICK_COND(mpx_umul, maybe_umul4_x86_sse2, cpu_feature_p(CPUFEAT_X86_SSE2)); #endif #if CPUFAM_AMD64 + DISPATCH_PICK_COND(mpx_umul, maybe_umul4_amd64_avx, + cpu_feature_p(CPUFEAT_X86_AVX)); DISPATCH_PICK_COND(mpx_umul, maybe_umul4_amd64_sse2, cpu_feature_p(CPUFEAT_X86_SSE2)); #endif diff --git a/math/pgen-granfrob.c b/math/pgen-granfrob.c new file mode 100644 index 00000000..98c8f8cb --- /dev/null +++ b/math/pgen-granfrob.c @@ -0,0 +1,276 @@ +/* -*-c-*- + * + * Grantham's Frobenius primality test + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "mp.h" +#include "mpmont.h" +#include "mpscan.h" +#include "pgen.h" + +#include "mptext.h" + +/*----- Main code ---------------------------------------------------------*/ + +static int squarep(mp *n) +{ + mp *t = MP_NEW; + int rc; + + if (MP_NEGP(n)) return (0); + t = mp_sqrt(t, n); t = mp_sqr(t, t); + rc = MP_EQ(t, n); mp_drop(t); return (rc); +} + +/* --- @pgen_granfrob@ --- * + * + * Arguments: @mp *n@ = an integer to test + * @int a, b@ = coefficients; if @a@ is zero then choose + * automatically + * + * Returns: One of the @PGEN_...@ codes. + * + * Use: Performs a quadratic version of Grantham's Frobenius + * primality test, which is a simple extension of the standard + * Lucas test. + * + * If %$a^2 - 4 b$% is a perfect square then the test can't + * work; this function returns @PGEN_ABORT@ under these + * circumstances. + */ + +int pgen_granfrob(mp *n, int a, int b) +{ + mp *v = MP_NEW, *w = MP_NEW, *aa = MP_NEW, *bb = MP_NEW, *bi = MP_NEW, + *k = MP_NEW, *x = MP_NEW, *y = MP_NEW, *z = MP_NEW, *t, *u; + mp ma; mpw wa; + mp mb; mpw wb; + mp md; mpw wd; int d; + mpmont mm; + mpscan msc; + int e, bit, rc; + + /* Maybe this is a no-hoper. */ + if (MP_NEGP(n)) return (PGEN_FAIL); + if (MP_EQ(n, MP_TWO)) return (PGEN_DONE); + if (!MP_ODDP(n)) return (PGEN_FAIL); + + /* First, build the parameters as large integers. */ + mp_build(&ma, &wa, &wa + 1); mp_build(&mb, &wb, &wb + 1); + mp_build(&md, &wd, &wd + 1); + mpmont_create(&mm, n); + + /* Prepare the Lucas sequence parameters. Here, %$\Delta$% is the + * disciminant of the polynomial %$p(x) = x^2 - a x + b$%, i.e., + * %$\Delta = a^2 - 4 b$%. + */ + if (a) { + /* Explicit parameters. Just set them and check that they'll work. */ + + if (a >= 0) wa = a; else { wa = -a; ma.f |= MP_NEG; } + if (b >= 0) wb = b; else { wb = -b; mb.f |= MP_NEG; } + d = a*a - 4*b; + if (d >= 0) wd = d; else { wd = -d; md.f |= MP_NEG; } + + /* Determine the quadratic character of %$\Delta$%. If %$(\Delta | n)$% + * is zero then we'll have a problem, but we'll catch that case with the + * GCD check below. + */ + e = mp_jacobi(&md, n); + + /* If %$\Delta$% is a perfect square then the test can't work. */ + if (e == 1 && squarep(&md)) { rc = PGEN_ABORT; goto end; } + } else { + /* Determine parameters. Use Selfridge's `Method A': choose the first + * %$\Delta$% from the sequence %$5$%, %$-7$%, %%\dots%%, such that + * %$(\Delta | n) = -1$%. + */ + + wa = 1; wd = 5; + for (;;) { + e = mp_jacobi(&md, n); if (e != +1) break; + if (wd == 25 && squarep(n)) { rc = PGEN_FAIL; goto end; } + wd += 2; md.f ^= MP_NEG; + } + a = 1; d = wd; + if (md.f&MP_NEG) { wb = (wd + 1)/4; d = -d; } + else { wb = (wd - 1)/4; mb.f |= MP_NEG; } + b = (1 - d)/4; + } + + /* The test won't work if %$\gcd(2 a b \Delta, n) \ne 1$%. */ + x = mp_lsl(x, &ma, 1); x = mp_mul(x, x, &mb); x = mp_mul(x, x, &md); + mp_gcd(&y, 0, 0, x, n); + if (!MP_EQ(y, MP_ONE)) + { rc = MP_EQ(y, n) ? PGEN_ABORT : PGEN_FAIL; goto end; } + + /* Now we use binary a Lucas chain to evaluate %$V_{n-e}(a, b) \pmod{n}$%. + * Here, + * + * * %$U_{i+1}(a, b) = a U_i(a, b) - b U_{i-1}(a, b)$%, and + * * %$V_{i+1}(a, b) = a V_i(a, b) - b V_{i-1}(a, b)$%; with + * * %$U_0(a, b) = 0$%, $%U_1(a, b) = 1$%, %$V_0(a, b) = 2$%, and + * %$V_1(a, b) = a$%. + * + * To compute this, we use the handy identities + * + * %$V_{i+j}(a, b) = V_i(a, b) V_j(a, b) - b^i V_{j-i}(a, b)$% + * + * and + * + * %$U_i(a, b) = (2 V_{i+1}(a, b) - a V_i(a, b))/\Delta$%. + * + * Let %$k = n - e$%. Given %$V_i(a, b)$% and %$V_{i+1}(a, b)$%, we can + * determine either %$V_{2i}(a, b)$% and %$V_{2i+1}(a, b)$%, or + * %$V_{2i+1}(a, b)$% and %$V_{2i+2}(a, b)$%. + * + * To do this, suppose that %$n < 2^\ell$% and %$0 \le i \le \ell%; we'll + * start with %$i = 0$%. Divide %$n = n_i 2^{\ell-i} + n'_i$% with + * %$n'_i < 2^{\ell-i}$%. To do this, we maintain %$v_i = V_{n_i}(a, b)$%, + * %$w_i = V_{n_i+1}(a, b)$%, and %$b_i = b^{n_i}$%, all modulo %$n$%. If + * %$n'_i < 2^{\ell-i-1}$% then we have %$n'_{i+1} = n'_i$% and + * %$n_{i+i} = 2 n_i$%; otherwise %$n'_{i+1} = n'_i - 2^{\ell-i-1}$% and + * %$n_{i+i} = 2 n_i + 1$%. + */ + k = mp_add(k, n, e > 0 ? MP_MONE : MP_ONE); + aa = mpmont_mul(&mm, aa, &ma, mm.r2); + bb = mpmont_mul(&mm, bb, &mb, mm.r2); bi = MP_COPY(mm.r); + v = mpmont_mul(&mm, v, MP_TWO, mm.r2); w = MP_COPY(aa); + + for (mpscan_rinitx(&msc, k->v, k->vl); mpscan_rstep(&msc); ) { + bit = mpscan_rbit(&msc); + + /* We will want %$x = V_{n_i+1}(a, b) = V_{n_i} V_{n_i+1} - a b^{n_i}$%, + * but we don't yet know whether this is %$v_{i+1}$% or %$w_{i+1}$%. + */ + x = mpmont_mul(&mm, x, v, w); + if (a == 1) x = mp_sub(x, x, bi); + else { y = mpmont_mul(&mm, y, aa, bi); x = mp_sub(x, x, y); } + if (MP_NEGP(x)) x = mp_add(x, x, n); + + if (!bit) { + /* We're in the former case: %$n_{i+i} = 2 n_i$%. So %$w_{i+1} = x$%, + * %$v_{i+1} = (v_i^2 - 2 b_i$%, and %$b_{i+1} = b_i^2$%. + */ + + y = mp_sqr(y, v); y = mpmont_reduce(&mm, y, y); + y = mp_sub(y, y, bi); if (MP_NEGP(y)) y = mp_add(y, y, n); + y = mp_sub(y, y, bi); if (MP_NEGP(y)) y = mp_add(y, y, n); + bi = mp_sqr(bi, bi); bi = mpmont_reduce(&mm, bi, bi); + t = v; u = w; v = y; w = x; x = t; y = u; + } else { + /* We're in the former case: %$n_{i+i} = 2 n_i + 1$%. So + * %$v_{i+1} = x$%, %$w_{i+1} = w_i^2 - 2 b b^i$%$%, and + * %$b_{i+1} = b b_i^2$%. + */ + + y = mp_sqr(y, w); y = mpmont_reduce(&mm, y, y); + z = mpmont_mul(&mm, z, bi, bb); + y = mp_sub(y, y, z); if (MP_NEGP(y)) y = mp_add(y, y, n); + y = mp_sub(y, y, z); if (MP_NEGP(y)) y = mp_add(y, y, n); + bi = mpmont_mul(&mm, bi, bi, z); + t = v; u = w; v = x; w = y; x = t; y = u; + } + } + + /* The Lucas test is that %$U_k(a, b) \equiv 0 \pmod{n}$% if %$n$% is + * prime. I'm assured that + * + * %$U_k(a, b) = (2 V_{k+1}(a, b) - a V_k(a, b))/\Delta$% + * + * so this is just a matter of checking that %$2 w - a v \equiv 0$%. + */ + x = mp_add(x, w, w); y = mp_sub(y, x, n); + if (!MP_NEGP(y)) { t = x; x = y; y = t; } + if (a == 1) x = mp_sub(x, x, v); + else { y = mpmont_mul(&mm, y, v, aa); x = mp_sub(x, x, y); } + if (MP_NEGP(x)) x = mp_add(x, x, n); + if (!MP_ZEROP(x)) { rc = PGEN_FAIL; goto end; } + + /* Grantham's Frobenius test is that, also, %$V_k(a, b) v = \equiv 2 b$% + * if %$n$% is prime and %$(\Delta | n) = -1$%, or %$v \equiv 2$% if + * %$(\Delta | n) = +1$%. + */ + if (MP_ODDP(v)) v = mp_add(v, v, n); + v = mp_lsr(v, v, 1); + if (!MP_EQ(v, e == +1 ? mm.r : bb)) { rc = PGEN_FAIL; goto end; } + + /* Looks like we made it. */ + rc = PGEN_PASS; +end: + mp_drop(v); mp_drop(w); mp_drop(aa); mp_drop(bb); mp_drop(bi); + mp_drop(k); mp_drop(x); mp_drop(y); mp_drop(z); + mpmont_destroy(&mm); + return (rc); +} + +/*----- Test rig ----------------------------------------------------------*/ + +#ifdef TEST_RIG + +#include + +#include "mptext.h" + +static int verify(dstr *v) +{ + mp *n = *(mp **)v[0].buf; + int a = *(int *)v[1].buf, b = *(int *)v[2].buf, xrc = *(int *)v[3].buf, rc; + int ok = 1; + + rc = pgen_granfrob(n, a, b); + if (rc != xrc) { + fputs("\n*** pgen_granfrob failed", stdout); + fputs("\nn = ", stdout); mp_writefile(n, stdout, 10); + printf("\na = %d", a); + printf("\nb = %d", a); + printf("\nexp rc = %d", xrc); + printf("\ncalc rc = %d\n", rc); + ok = 0; + } + + mp_drop(n); + assert(mparena_count(MPARENA_GLOBAL) == 0); + return (ok); +} + +static test_chunk tests[] = { + { "pgen-granfrob", verify, + { &type_mp, &type_int, &type_int, &type_int, 0 } }, + { 0, 0, { 0 } } +}; + +int main(int argc, char *argv[]) +{ + sub_init(); + test_run(argc, argv, tests, SRCDIR "/t/pgen"); + return (0); +} + +#endif + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/math/pgen.c b/math/pgen.c index 84185e33..f0606591 100644 --- a/math/pgen.c +++ b/math/pgen.c @@ -319,28 +319,33 @@ mp *pgen(const char *name, mp *d, mp *m, pgen_proc *event, void *ectx, * @grand *gr@ = a random number source * * Returns: Nonzero if @p@ is really prime. + * + * Use: Checks the primality of @p@. If @p@ is prime, then this + * function returns nonzero; if @p@ is really composite then it + * %%\emph{probably}%% returns zero, but might not. + * + * Currently, this function uses the Baillie--PSW test, which + * combines a single Miller--Rabin test with witness 2 with a + * single Frobenius test with parameters chosen using + * Selfridge's `Method A'. No composites are known which pass + * this test, though it's conjectured that infinitely many + * exist. */ int pgen_primep(mp *p, grand *gr) { - int i; rabin r; - mp *x = MP_NEW; + int rc; if (MP_NEGP(p)) return (0); switch (pfilt_smallfactor(p)) { case PGEN_DONE: return (1); case PGEN_FAIL: return (0); } - rabin_create(&r, p); - for (i = 32; i; i--) { - x = mprand_range(x, p, gr, 0); - if (rabin_rtest(&r, x) == PGEN_FAIL) - break; - } - MP_DROP(x); - rabin_destroy(&r); - return (!i); + rabin_create(&r, p); rc = rabin_test(&r, MP_TWO); rabin_destroy(&r); + if (rc == PGEN_FAIL) return (0); + rc = pgen_granfrob(p, 0, 0); if (rc == PGEN_FAIL) return (0); + return (1); } /*----- Test rig ----------------------------------------------------------*/ diff --git a/math/pgen.h b/math/pgen.h index b103c30e..eef91414 100644 --- a/math/pgen.h +++ b/math/pgen.h @@ -270,6 +270,29 @@ extern mp *pgen(const char */*name*/, mp */*d*/, mp */*m*/, unsigned /*steps*/, pgen_proc */*step*/, void */*sctx*/, unsigned /*tests*/, pgen_proc */*test*/, void */*tctx*/); +/* --- @pgen_granfrob@ --- * + * + * Arguments: @mp *n@ = an integer to test + * @int a, b@ = coefficients; if @a@ is zero then choose + * automatically + * + * Returns: One of the @PGEN_...@ codes. + * + * Use: Performs a quadratic version of Grantham's Frobenius + * primality test, which is a simple extension of the standard + * Lucas test. + * + * If %$a^2 - 4 b$% is a perfect square then the test can't + * work; this function returns @PGEN_ABORT@ under these + * circumstances. + * + * If @a@ is zero on entry, then the function will choose + * suitable parameters deterministically -- i.e., it always + * chooses the same parameters for a given %$n$%. + */ + +extern int pgen_granfrob(mp */*n*/, int /*a*/, int /*b*/); + /* --- @pgen_primep@ --- * * * Arguments: @mp *p@ = a number to check diff --git a/math/t/pgen b/math/t/pgen index 8d52d197..be26c183 100644 --- a/math/t/pgen +++ b/math/t/pgen @@ -14,6 +14,29 @@ pgen { 166359567317705838255275971708060308423814413741683015010175247351623188739655446196925981468626681882384215574706593049022467680136399439302347043107836749816290369600677730213469006507173065402294688841278559283358390567733443050775707749725690534182003442070447739085348456478911335969765393755383551520173 166359567317705838255275971708060308423814413741683015010175247351623188739655446196925981468626681882384215574706593049022467680136399439302347043107836749816290369600677730213469006507173065402294688841278559283358390567733443050775707749725690534182003442070447739085348456478911335969765393755383551520257; } +pgen-granfrob { + 5 0 0 -1; + 7 0 0 4; + 15 0 0 3; + 5777 1 -1 4; # pseudoprime + 40301809 0 0 4; + 86059163416987297647409667483582114939806237974424324409828198660056356336227 1 5 4; + 102508420970861015999300753620309481186457893679971500520427161277511389396803 1 5 4; + 72291866454056552194087337607224612505157525245486245416393486917859196707519 1 5 4; + 72291866454056552194087337607224612505157525245486265416393486917859196707519 1 5 3; + + ## A large Frobenius pseudoprime: call the first number p_1; then p_2 = 31 + ## (p_1 + 1) - 1 and p_3 = 43 (p_1 + 1) - 1. These three are all prime. + ## Their product is a strong Lucas, and Frobenius, pseudoprime. + ## + ## See `Prime and Prejudice' by Martin R. Albrecht, Jake Massimo, Kenneth + ## G. Paterson, and Juraj Somorovsky. + 3690125385954346893658786222051913500627130245213169388019826598097107079718295481926241398412699320815932808015860263240282855670239765686869973444864115322609857375876438922226372746215468824202413623127 0 0 4; + 114393886964584753703422372883609318519441037601608251028614624541010319471267159939713483350793678945293917048491668160448768525777432736292969176790787575000905578652169606589017555132679533550274822316967 0 0 4; + 158675391596036916427327807548232280526966600544166283684852543718175604427886705722828380131746070795085110744681991319332162793820309924535408858129156958872223867162686873655734028087265159440703785794503 0 0 4; + 66981291792500223036804182765508448534715465524671325885174850970812009004775815201151227900130153990294748113034471984909912807896550069799856170439734910206802409847773026240559371480115711600866989845251707737806461503879250232804362190067578216069266197879151809743235261582813331022213587929425243163096486125825510076936556242805690400001899138503900919499414951069309064408305196756524628693684938044145785145327821174180933033293089394794328963673467918652042794300291355500468079109432376296868174257674548727592142782202898031102246775544402811199608266683925072825828225074019194302318324623049819212337927 0 0 4; +} + primep { -5 0; -1 0; @@ -24,6 +47,30 @@ primep { 4 0; 40301809 1; 40301811 0; + + ## A small Lucas pseudoprime: 5777 = 53*109. + 5777 0; + + ## A large strong pseudoprime: this is the product of + ## + ## p_1 = 142445387161415482404826365418175962266689133006163 + ## p_2 = 5840260873618034778597880982145214452934254453252643 + ## p_3 = 14386984103302963722887462907235772188935602433622363 + ## + ## See `Prime and Prejudice' by Martin R. Albrecht, Jake Massimo, Kenneth + ## G. Paterson, and Juraj Somorovsky. + 142445387161415482404826365418175962266689133006163 1; + 5840260873618034778597880982145214452934254453252643 1; + 14386984103302963722887462907235772188935602433622363 1; + 11968794224604718293549908104759518204343930652759288592987578098131927050572705181539873293848476235393230314654912729920657864630317971562727057595285667 0; + + ## A large Lucas pseudoprime: call the first number p_1; then p_2 = 31 (p_1 + ## + 1) - 1 and p_3 = 43 (p_1 + 1) - 1. These three are all prime. Their + ## product is a strong Lucas pseudoprime. + 3690125385954346893658786222051913500627130245213169388019826598097107079718295481926241398412699320815932808015860263240282855670239765686869973444864115322609857375876438922226372746215468824202413623127 1; + 114393886964584753703422372883609318519441037601608251028614624541010319471267159939713483350793678945293917048491668160448768525777432736292969176790787575000905578652169606589017555132679533550274822316967 1; + 158675391596036916427327807548232280526966600544166283684852543718175604427886705722828380131746070795085110744681991319332162793820309924535408858129156958872223867162686873655734028087265159440703785794503 1; + 66981291792500223036804182765508448534715465524671325885174850970812009004775815201151227900130153990294748113034471984909912807896550069799856170439734910206802409847773026240559371480115711600866989845251707737806461503879250232804362190067578216069266197879151809743235261582813331022213587929425243163096486125825510076936556242805690400001899138503900919499414951069309064408305196756524628693684938044145785145327821174180933033293089394794328963673467918652042794300291355500468079109432376296868174257674548727592142782202898031102246775544402811199608266683925072825828225074019194302318324623049819212337927 0; } primeiter { diff --git a/progs/.gitignore b/progs/.gitignore new file mode 100644 index 00000000..b46a9e8e --- /dev/null +++ b/progs/.gitignore @@ -0,0 +1,2 @@ +/getdate.h +/getdate.y diff --git a/progs/Makefile.am b/progs/Makefile.am index 5f4e570c..6de619f6 100644 --- a/progs/Makefile.am +++ b/progs/Makefile.am @@ -99,7 +99,9 @@ bin_PROGRAMS += perftest ## Remember passphrases for limited periods of time. bin_PROGRAMS += pixie pixie_SOURCES = pixie.c -pixie_LDADD = $(UTILS_LIBS) $(PIXIE_LIBS) $(LOGLIBS) +pixie_LDADD = $(top_builddir)/base/libbase.la +pixie_LDADD += $(top_builddir)/key/libkey.la +pixie_LDADD += $(mLib_LIBS) $(PIXIE_LIBS) $(LOGLIBS) dist_man_MANS += pixie.1 EXTRA_DIST += xpixie diff --git a/progs/catcrypt.1 b/progs/catcrypt.1 index 6c554408..d944bfab 100644 --- a/progs/catcrypt.1 +++ b/progs/catcrypt.1 @@ -248,9 +248,23 @@ Makes use of .B cipher and .B mac -attributes. +attributes. Run +.B catcrypt show cipher +for a list of supported symmetric encryption algorithms; the default +.I cipher +is +.BR blowfish-cbc . This is the default transform. .TP +.B aead +Use an `authenticated encryption with additional data' (AEAD) scheme. +The specific scheme is named by the +.B cipher +attribute. Run +.B catcrypt show aead +for a list of supported AEAD schemes; the default is +.BR chacha20-poly1305 . +.TP .B naclbox Use Salsa20 or ChaCha and Poly1305 to secure the bulk data. This is nearly the same as the NaCl @@ -272,6 +286,11 @@ or .BR chacha8 ; the default is .BR salsa20 . +Nowadays, this is equivalent to the +.B aead +transform, using +.IB cipher -naclbox +as the cipher. .PP As well as the KEM itself, a number of supporting algorithms are used. These are taken from appropriately named attributes on the key or, @@ -286,11 +305,8 @@ attribute then the .I bulk in the .I kemalgspec -is used; if that it absent, then the default of -.B blowfish-cbc -is used. Run -.B catcrypt show cipher -for a list of supported symmetric encryption algorithms. +is used; if that it absent, then the default depends on the bulk +transform. .TP .B hash This is the hash function used to distil entropy from the shared secret @@ -559,24 +575,26 @@ key-encapsulation key's attribute. .TP .B cipher -The symmetric encryption algorithms which can be used in a +The symmetric encryption algorithms which can be named in a key-encapsulation key's .B cipher -attribute. +attribute when using the +.B gencomp +bulk transform. .TP .B mac -The message authentication algorithms which can be used in a +The message authentication algorithms which can be named in a key-encapsulation key's .B mac attribute. .TP .B sig -The signature algorithms which can be used in a signing key's +The signature algorithms which can be named in a signing key's .B sig attribute. .TP .B hash -The hash functions which can be used in a key's +The hash functions which can be named in a key's .B hash attribute. .TP diff --git a/progs/catcrypt.c b/progs/catcrypt.c index 72c77807..c31a3d93 100644 --- a/progs/catcrypt.c +++ b/progs/catcrypt.c @@ -51,6 +51,7 @@ #include "key.h" #include "cc.h" +#include "gaead.h" #include "ectab.h" #include "ptab.h" @@ -572,6 +573,8 @@ static int decrypt(int argc, char *argv[]) enctab[i].name, enctab[i].name) \ LI("Symmetric encryption algorithms", cipher, \ gciphertab[i], gciphertab[i]->name) \ + LI("Authenticated encryption schemes", aead, \ + gaeadtab[i], gaeadtab[i]->name) \ LI("Hash functions", hash, \ ghashtab[i], ghashtab[i]->name) \ LI("Message authentication codes", mac, \ diff --git a/progs/cc-kem.c b/progs/cc-kem.c index 1e99e05d..9159ade7 100644 --- a/progs/cc-kem.c +++ b/progs/cc-kem.c @@ -36,6 +36,7 @@ #include #include +#include "gaead.h" #include "mprand.h" #include "rand.h" @@ -48,6 +49,7 @@ #include "rmd160.h" #include "blowfish-cbc.h" +#include "chacha20-poly1305.h" #include "poly1305.h" #include "salsa20.h" #include "chacha.h" @@ -56,113 +58,180 @@ /*----- Bulk crypto -------------------------------------------------------*/ -/* --- NaCl `secretbox' --- */ +/* --- Authenticated encryption schemes --- */ -typedef struct naclbox_encctx { +typedef struct aead_encctx { bulk b; - const gccipher *cc; - gcipher *c; -} naclbox_encctx; + const gcaead *aec; + gaead_key *key; + union { gaead_enc *enc; gaead_dec *dec; } ed; + octet *t; + size_t nsz, tsz; +} aead_encctx; -static bulk *naclbox_init(key *k, const char *calg, const char *halg) +static bulk *aead_internalinit(key *k, const gcaead *aec) { - naclbox_encctx *ctx = CREATE(naclbox_encctx); - dstr t = DSTR_INIT; + aead_encctx *ctx = CREATE(aead_encctx); + + ctx->key = 0; + ctx->aec = aec; + if ((ctx->nsz = keysz_pad(4, aec->noncesz)) == 0) + die(EXIT_FAILURE, "no suitable nonce size for `%s'", aec->name); + ctx->tsz = keysz(0, ctx->aec->tagsz); + + return (&ctx->b); +} + +static bulk *aead_init(key *k, const char *calg, const char *halg) +{ + const gcaead *aec; const char *q; + dstr t = DSTR_INIT; key_fulltag(k, &t); if ((q = key_getattr(0, k, "cipher")) != 0) calg = q; - if (!calg || strcmp(calg, "salsa20") == 0) ctx->cc = &salsa20; - else if (strcmp(calg, "salsa20/12") == 0) ctx->cc = &salsa2012; - else if (strcmp(calg, "salsa20/8") == 0) ctx->cc = &salsa208; - else if (strcmp(calg, "chacha20") == 0) ctx->cc = &chacha20; - else if (strcmp(calg, "chacha12") == 0) ctx->cc = &chacha12; - else if (strcmp(calg, "chacha8") == 0) ctx->cc = &chacha8; - else { - die(EXIT_FAILURE, - "unknown or inappropriate encryption scheme `%s' in key `%s'", + if (!calg) aec = &chacha20_poly1305; + else if ((aec = gaead_byname(calg)) == 0) + die(EXIT_FAILURE, "AEAD scheme `%s' not found in key `%s'", calg, t.buf); - } dstr_destroy(&t); - return (&ctx->b); + return (aead_internalinit(k, aec)); } -static int naclbox_setup(bulk *b, gcipher *cx) +static int aead_commonsetup(aead_encctx *ctx, gcipher *cx) { - naclbox_encctx *ctx = (naclbox_encctx *)b; - octet k[SALSA20_KEYSZ]; + size_t ksz, n; - GC_ENCRYPT(cx, 0, k, sizeof(k)); - ctx->c = GC_INIT(ctx->cc, k, sizeof(k)); + n = ksz = keysz(0, ctx->aec->keysz); + if (n < ctx->nsz) n = ctx->nsz; + if (n < ctx->tsz) n = ctx->tsz; + ctx->t = xmalloc(n); + + GC_ENCRYPT(cx, 0, ctx->t, ksz); + ctx->key = GAEAD_KEY(ctx->aec, ctx->t, ksz); return (0); } -static size_t naclbox_overhead(bulk *b) { return (POLY1305_TAGSZ); } +static size_t aead_overhead(bulk *b) + { aead_encctx *ctx = (aead_encctx *)b; return (ctx->aec->ohd + ctx->tsz); } -static void naclbox_destroy(bulk *b) +static void aead_commondestroy(aead_encctx *ctx) { - naclbox_encctx *ctx = (naclbox_encctx *)b; - - GC_DESTROY(ctx->c); + if (ctx->key) GAEAD_DESTROY(ctx->key); + xfree(ctx->t); DESTROY(ctx); } -static const char *naclbox_encdoit(bulk *b, uint32 seq, buf *bb, - const void *p, size_t sz) +static int aead_encsetup(bulk *b, gcipher *cx) { - naclbox_encctx *ctx = (naclbox_encctx *)b; - octet t[32]; - poly1305_key ak; - poly1305_ctx a; - octet *tag, *ct; + aead_encctx *ctx = (aead_encctx *)b; + ctx->ed.enc = 0; return (aead_commonsetup(ctx, cx)); +} - STORE32(t, seq); STORE32(t + 4, 0); GC_SETIV(ctx->c, t); - GC_ENCRYPT(ctx->c, 0, t, POLY1305_KEYSZ + POLY1305_MASKSZ); - poly1305_keyinit(&ak, t, POLY1305_KEYSZ); - poly1305_macinit(&a, &ak, t + POLY1305_KEYSZ); +static const char *aead_encdoit(bulk *b, uint32 seq, buf *bb, + const void *p, size_t sz) +{ + aead_encctx *ctx = (aead_encctx *)b; + octet *t; + int rc; - tag = buf_get(bb, POLY1305_TAGSZ); assert(tag); - ct = buf_get(bb, sz); assert(ct); - GC_ENCRYPT(ctx->c, p, ct, sz); - poly1305_hash(&a, ct, sz); - poly1305_done(&a, tag); + memset(ctx->t + 4, 0, ctx->nsz - 4); STORE32_B(ctx->t, seq); + if (!ctx->ed.enc) + ctx->ed.enc = GAEAD_ENC(ctx->key, ctx->t, ctx->nsz, 0, sz, ctx->tsz); + else + GAEAD_REINIT(ctx->ed.enc, ctx->t, ctx->nsz, 0, sz, ctx->tsz); + t = buf_get(bb, ctx->tsz); assert(t); + rc = GAEAD_ENCRYPT(ctx->ed.enc, p, sz, bb); assert(rc >= 0); + rc = GAEAD_DONE(ctx->ed.enc, 0, bb, t, ctx->tsz); assert(rc >= 0); return (0); } -static const char *naclbox_decdoit(bulk *b, uint32 seq, buf *bb, - const void *p, size_t sz) +static void aead_encdestroy(bulk *b) +{ + aead_encctx *ctx = (aead_encctx *)b; + if (ctx->ed.enc) GAEAD_DESTROY(ctx->ed.enc); + aead_commondestroy(ctx); +} + +static int aead_decsetup(bulk *b, gcipher *cx) { - naclbox_encctx *ctx = (naclbox_encctx *)b; + aead_encctx *ctx = (aead_encctx *)b; + ctx->ed.dec = 0; return (aead_commonsetup(ctx, cx)); +} + +static const char *aead_decdoit(bulk *b, uint32 seq, buf *bb, + const void *p, size_t sz) +{ + aead_encctx *ctx = (aead_encctx *)b; buf bin; - octet t[32]; - poly1305_key ak; - poly1305_ctx a; - octet *tag, *ct, *pt; + const octet *t; + int rc; - STORE32(t, seq); STORE32(t + 4, 0); GC_SETIV(ctx->c, t); - GC_ENCRYPT(ctx->c, 0, t, POLY1305_KEYSZ + POLY1305_MASKSZ); - poly1305_keyinit(&ak, t, POLY1305_KEYSZ); - poly1305_macinit(&a, &ak, t + POLY1305_KEYSZ); + memset(ctx->t + 4, 0, ctx->nsz - 4); STORE32_B(ctx->t, seq); + if (!ctx->ed.dec) + ctx->ed.dec = GAEAD_DEC(ctx->key, ctx->t, ctx->nsz, 0, sz, ctx->tsz); + else + GAEAD_REINIT(ctx->ed.enc, ctx->t, ctx->nsz, 0, sz, ctx->tsz); buf_init(&bin, (/*unconst*/ void *)p, sz); - if ((tag = buf_get(&bin, POLY1305_TAGSZ)) == 0) return ("no tag"); - ct = BCUR(&bin); sz = BLEFT(&bin); - poly1305_hash(&a, ct, sz); - poly1305_done(&a, t); - if (!ct_memeq(t, tag, POLY1305_TAGSZ)) return ("authentication failure"); - pt = buf_get(bb, sz); assert(pt); - GC_DECRYPT(ctx->c, ct, pt, sz); + t = buf_get(&bin, ctx->tsz); if (!t) return ("no tag"); + rc = GAEAD_DECRYPT(ctx->ed.dec, BCUR(&bin), BLEFT(&bin), bb); + assert(rc >= 0); + rc = GAEAD_DONE(ctx->ed.dec, 0, bb, t, ctx->tsz); assert(rc >= 0); + if (!rc) return ("authentication failure"); return (0); } +static void aead_decdestroy(bulk *b) +{ + aead_encctx *ctx = (aead_encctx *)b; + if (ctx->ed.dec) GAEAD_DESTROY(ctx->ed.dec); + aead_commondestroy(ctx); +} + +static const struct bulkops aead_encops = { + aead_init, aead_encsetup, aead_overhead, + aead_encdoit, aead_encdestroy +}, aead_decops = { + aead_init, aead_decsetup, aead_overhead, + aead_decdoit, aead_decdestroy +}; + +/* --- NaCl `secretbox' in terms of AEAD --- */ + +static bulk *naclbox_init(key *k, const char *calg, const char *halg) +{ + const gcaead *aec; + dstr t = DSTR_INIT; + const char *q; + + key_fulltag(k, &t); + + if ((q = key_getattr(0, k, "cipher")) != 0) calg = q; + if (!calg || strcmp(calg, "salsa20") == 0) aec = &salsa20_naclbox; + else if (strcmp(calg, "salsa20/12") == 0) aec = &salsa2012_naclbox; + else if (strcmp(calg, "salsa20/8") == 0) aec = &salsa208_naclbox; + else if (strcmp(calg, "chacha20") == 0) aec = &chacha20_naclbox; + else if (strcmp(calg, "chacha12") == 0) aec = &chacha12_naclbox; + else if (strcmp(calg, "chacha8") == 0) aec = &chacha8_naclbox; + else { + die(EXIT_FAILURE, + "unknown or inappropriate encryption scheme `%s' in key `%s'", + calg, t.buf); + } + + dstr_destroy(&t); + return (aead_internalinit(k, aec)); +} + static const bulkops naclbox_encops = { - naclbox_init, naclbox_setup, naclbox_overhead, - naclbox_encdoit, naclbox_destroy + naclbox_init, aead_encsetup, aead_overhead, + aead_encdoit, aead_encdestroy }, naclbox_decops = { - naclbox_init, naclbox_setup, naclbox_overhead, - naclbox_decdoit, naclbox_destroy + naclbox_init, aead_decsetup, aead_overhead, + aead_decdoit, aead_decdestroy }; /* --- Generic composition --- */ @@ -300,6 +369,7 @@ static const bulkops gencomp_encops = { const struct bulktab bulktab[] = { { "gencomp", &gencomp_encops, &gencomp_decops }, { "naclbox", &naclbox_encops, &naclbox_decops }, + { "aead", &aead_encops, &aead_decops }, { 0, 0, 0 } }; diff --git a/progs/perftest.c b/progs/perftest.c index 8b7d3d2c..6af4d515 100644 --- a/progs/perftest.c +++ b/progs/perftest.c @@ -43,7 +43,13 @@ #include #include +#ifdef HAVE_LINUX_PERF_EVENT_H +# include +# include +#endif + #include +#include #include #include #include @@ -70,6 +76,7 @@ #include "ed448.h" #include "cc.h" +#include "gaead.h" #include "gcipher.h" #include "ghash.h" #include "gmac.h" @@ -82,10 +89,13 @@ typedef struct opts { const char *name; /* Pre-configured named thing */ + const char *opwhat; /* What to call operations */ unsigned fbits; /* Field size bits */ unsigned gbits; /* Group size bits */ unsigned n; /* Number of factors */ unsigned i; /* Number of intervals (or zero) */ + unsigned k; /* Main loop batch size */ + unsigned long sc; /* Scale factor */ double t; /* Time for each interval (secs) */ mp *e; /* Public exponent */ unsigned f; /* Flags */ @@ -495,7 +505,9 @@ static void *ksched_init(opts *o) die(1, "must specify encryption scheme name"); if ((c->c = gcipher_byname(o->name)) == 0) die(1, "encryption scheme `%s' not known", o->name); - c->ksz = keysz(o->gbits/8, c->c->keysz); + c->ksz = keysz(o->fbits/8, c->c->keysz); + if (o->fbits%8 || (o->fbits && c->ksz != o->fbits/8)) + die(1, "bad key size %u for %s", o->fbits, o->name); c->k = xmalloc(c->ksz); rand_get(RAND_GLOBAL, c->k, c->ksz); return (c); @@ -525,13 +537,16 @@ static void *enc_init(opts *o) die(1, "must specify encryption scheme name"); if ((cc = gcipher_byname(o->name)) == 0) die(1, "encryption scheme `%s' not known", o->name); - ksz = keysz(0, cc->keysz); + ksz = keysz(o->fbits/8, cc->keysz); + if (o->fbits%8 || (o->fbits && ksz != o->fbits/8)) + die(1, "bad key size %u for %s", o->fbits, o->name); k = xmalloc(ksz); rand_get(RAND_GLOBAL, k, ksz); c->c = GC_INIT(cc, k, ksz); xfree(k); c->sz = o->gbits ? o->gbits : 65536; c->n = o->n ? o->n : 16; + o->opwhat = "byte"; o->sc = c->n*c->sz; c->m = xmalloc(c->sz); return (c); } @@ -544,6 +559,105 @@ static void enc_run(void *cc) GC_ENCRYPT(c->c, c->m, c->m, c->sz); } +/* --- Authenticated encryption --- */ + +typedef struct aeadsetup_ctx { + const gcaead *aec; + octet *k; size_t ksz; + octet *n; size_t nsz; + size_t tsz; +} aeadsetup_ctx; + +static void *aeadsetup_init(opts *o) +{ + aeadsetup_ctx *c = CREATE(aeadsetup_ctx); + if (!o->name) + die(1, "must specify encryption scheme name"); + if ((c->aec = gaead_byname(o->name)) == 0) + die(1, "aead scheme `%s' not known", o->name); + c->ksz = keysz(o->fbits/8, c->aec->keysz); + c->nsz = keysz_pad(o->gbits/8, c->aec->noncesz); + c->tsz = keysz(0, c->aec->tagsz); + if (o->fbits%8 || (o->fbits && c->ksz != o->fbits/8)) + die(1, "bad key size %u for %s", o->fbits, o->name); + if (o->gbits%8 || (o->gbits && c->nsz != o->gbits/8)) + die(1, "bad nonce size %u for %s", o->gbits, o->name); + c->k = xmalloc(c->ksz); rand_get(RAND_GLOBAL, c->k, c->ksz); + c->n = xmalloc(c->nsz); rand_get(RAND_GLOBAL, c->n, c->nsz); + return (c); +} + +static void aeadsetup_run(void *cc) +{ + aeadsetup_ctx *c = cc; + gaead_key *k = GAEAD_KEY(c->aec, c->k, c->ksz); + gaead_enc *e = GAEAD_ENC(k, c->n, c->nsz, 0, 0, c->tsz); + GAEAD_DESTROY(e); GAEAD_DESTROY(k); +} + +typedef struct aeadenc_ctx { + gaead_enc *enc; + octet *n; size_t nsz; + octet *p, *q; size_t sz; size_t nn; + size_t tsz; +} aeadenc_ctx; + +static void *aeadenc_init(opts *o) +{ + aeadenc_ctx *c = CREATE(aeadenc_ctx); + const gcaead *aec; + gaead_key *key; + octet *k; size_t ksz; + + if (!o->name) + die(1, "must specify encryption scheme name"); + if ((aec = gaead_byname(o->name)) == 0) + die(1, "aead scheme `%s' not known", o->name); + c->sz = o->gbits ? o->gbits : 65536; + c->nn = o->n ? o->n : 16; + ksz = keysz(o->fbits/8, aec->keysz); + c->nsz = keysz(0, aec->noncesz); + c->tsz = keysz(0, aec->tagsz); + if (o->fbits%8 || (o->fbits && ksz != o->fbits/8)) + die(1, "bad key size %u for %s", o->fbits, o->name); + + k = xmalloc(ksz); rand_get(RAND_GLOBAL, k, ksz); + c->n = xmalloc(c->nsz); rand_get(RAND_GLOBAL, c->n, c->nsz); + c->p = xmalloc(c->sz); c->q = xmalloc(c->sz + aec->bufsz); + + key = GAEAD_KEY(aec, k, ksz); + c->enc = GAEAD_ENC(key, c->n, c->nsz, 0, 0, c->tsz); + GAEAD_DESTROY(key); xfree(k); + + o->opwhat = "byte"; o->sc = c->nn*c->sz; + return (c); +} + +static void aeadaad_run(void *cc) +{ + aeadenc_ctx *c = cc; + gaead_aad *a; + size_t i; + + GAEAD_REINIT(c->enc, c->n, c->nsz, c->nn*c->sz, 0, c->tsz); + a = GAEAD_AAD(c->enc); + for (i = 0; i < c->nn; i++) GAEAD_HASH(a, c->p, c->sz); + GAEAD_DESTROY(a); +} + +static void aeadenc_run(void *cc) +{ + aeadenc_ctx *c = cc; + buf b; + size_t i; + + GAEAD_REINIT(c->enc, c->n, c->nsz, 0, c->nn*c->sz, c->tsz); + for (i = 0; i < c->nn; i++) { + buf_init(&b, c->q, c->sz + c->enc->ops->c->bufsz); + GAEAD_ENCRYPT(c->enc, c->p, c->sz, &b); + } +} + /* --- Hashing --- */ typedef struct hash_ctx { @@ -562,6 +676,7 @@ static void *hash_init(opts *o) die(1, "hash function `%s' not known", o->name); c->sz = o->gbits ? o->gbits : 65536; c->n = o->n ? o->n : 16; + o->opwhat = "byte"; o->sc = c->n*c->sz; c->m = xmalloc(c->sz); return (c); } @@ -596,6 +711,7 @@ static void *poly1305_jobinit(opts *o) rand_get(RAND_GLOBAL, c->s, sizeof(c->s)); c->sz = o->gbits ? o->gbits : 65536; c->n = o->n ? o->n : 16; + o->opwhat = "byte"; o->sc = c->n*c->sz; c->m = xmalloc(c->sz); return (c); } @@ -639,11 +755,81 @@ static const jobops jobtab[] = { { "ed448-vrf", ed448_vrfinit, ed448_vrfrun }, { "ksched", ksched_init, ksched_run }, { "enc", enc_init, enc_run }, + { "aead-setup", aeadsetup_init, aeadsetup_run }, + { "aead-aad", aeadenc_init, aeadaad_run }, + { "aead-enc", aeadenc_init, aeadenc_run }, { "hash", hash_init, hash_run }, { "poly1305", poly1305_jobinit, poly1305_jobrun }, { 0, 0, 0 } }; +/*----- Cycle counting ----------------------------------------------------*/ + +typedef kludge64 cycles; +static int cyclecount_active_p = 0; + +#if defined(__GNUC__) && (CPUFAM_X86 || CPUFAM_AMD64) + +static void init_cyclecount(void) { cyclecount_active_p = 1; } + +static cycles cyclecount(void) +{ + uint32 lo, hi; + kludge64 cy; + + __asm__("rdtsc" : "=a"(lo), "=d"(hi)); + SET64(cy, hi, lo); + return cy; +} + +#elif defined(HAVE_LINUX_PERF_EVENT_H) && defined(HAVE_UINT64) + +static int perf_fd = -1; + +static void init_cyclecount(void) +{ + struct perf_event_attr attr = { 0 }; + + attr.type = PERF_TYPE_HARDWARE; + attr.size = sizeof(attr); + attr.config = PERF_COUNT_HW_CPU_CYCLES; + attr.disabled = 0; + attr.exclude_kernel = 1; + attr.exclude_hv = 1; + + if ((perf_fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0)) < 0) + moan("failed to open perf event: %s", strerror(errno)); + else + cyclecount_active_p = 1; +} + +static cycles cyclecount(void) +{ + kludge64 cy; + ssize_t n; + + if (!cyclecount_active_p) + goto fail; + else if ((n = read(perf_fd, &cy.i, sizeof(cy.i))) != sizeof(cy.i)) { + if (n < 0) moan("error reading perf event: %s", strerror(errno)); + else moan("unexpected short read from perf event"); + cyclecount_active_p = 0; close(perf_fd); perf_fd = -1; + goto fail; + } +end: + return (cy); +fail: + SET64(cy, 0, 0); + goto end; +} + +#else + +static void init_cyclecount(void) { cyclecount_active_p = 0; } +static cycles cyclecount(void) { kludge64 cy; SET64(cy, 0, 0); return (cy); } + +#endif + /*----- Main code ---------------------------------------------------------*/ void version(FILE *fp) @@ -672,13 +858,15 @@ Options:\n\ -l, --list [ITEM...] List all the various names of things.\n\ \n\ -C, --name=NAME Select curve/DH-group/enc/hash name.\n\ --b, --field-bits Field size for g-prime and rsa.\n\ +-b, --field-bits Field size for g-prime and rsa;\n\ + key bits for ksched, enc, aead-setup, aead-enc.\n\ -q, --no-check Don't check field/group for validity.\n\ --B, --group-bits Group size for g-prime; key size for ksched;\n\ - data size for enc and hash.\n\ +-B, --group-bits Group size for g-prime; nonce bits for aead-setup;\n\ + data size for enc, aead-aad, aead-enc, and hash.\n\ -n, --factors=COUNT Number of factors for {exp,mul}-sim;\n\ - inner iterations for enc and hash.\n\ + inner iters for enc, aead-aad, aead-enc, hash.\n\ -i, --intervals=COUNT Number of intervals to run for. [0; forever]\n\ +-k, --batch=COUNT Number of operations to batch between timer checks.\n\ -t, --time=TIME Length of an interval in seconds. [1]\n\ "); } @@ -694,6 +882,8 @@ Options:\n\ ptab[i].name, ptab[i].name) \ LI("Encryption algorithms", cipher, \ gciphertab[i], gciphertab[i]->name) \ + LI("Authenticated encryption schemes", aead, \ + gaeadtab[i], gaeadtab[i]->name) \ LI("Hash functions", hash, \ ghashtab[i], ghashtab[i]->name) @@ -735,15 +925,16 @@ int main(int argc, char *argv[]) opts o = { 0 }; const jobops *j; struct timeval tv_next, tv_now; - double t, ttot; - unsigned n; + double t, ttot, cy, cytot; + unsigned n, k; unsigned long ii; - clock_t c_start, c_stop; + clock_t c0, c1; + kludge64 cy0, cy1, cydiff; double itot; void *p; ego(argv[0]); - o.t = 1; + o.t = 1; o.k = 1; o.sc = 1; o.opwhat = "op"; for (;;) { static const struct option opts[] = { { "help", 0, 0, 'h' }, @@ -755,13 +946,14 @@ int main(int argc, char *argv[]) { "group-bits", OPTF_ARGREQ, 0, 'B' }, { "factors", OPTF_ARGREQ, 0, 'n' }, { "intervals", OPTF_ARGREQ, 0, 'i' }, + { "batch", OPTF_ARGREQ, 0, 'k' }, { "public-exponent", OPTF_ARGREQ, 0, 'e' }, { "time", OPTF_ARGREQ, 0, 't' }, { "no-check", 0, 0, 'q' }, { 0, 0, 0, 0 } }; - i = mdwopt(argc, argv, "hvulC:b:B:n:i:e:t:q", opts, 0, 0, 0); + i = mdwopt(argc, argv, "hvulC:b:B:n:i:k:e:t:q", opts, 0, 0, 0); if (i < 0) break; switch (i) { case 'h': help(stdout); exit(0); @@ -779,6 +971,7 @@ int main(int argc, char *argv[]) break; case 'i': o.i = uarg("interval count", optarg); break; case 't': o.t = farg("interval length", optarg); break; + case 'k': o.k = uarg("batch size", optarg); break; case 'q': o.f |= OF_NOCHECK; break; default: usage(stderr); exit(1); } @@ -791,23 +984,29 @@ int main(int argc, char *argv[]) p = j->init(&o); n = 0; - ttot = itot = 0; + ttot = itot = 0; cytot = 0; init_cyclecount(); gettimeofday(&tv_now, 0); do { tv_addl(&tv_next, &tv_now, o.t, fmod(o.t * MILLION, MILLION)); ii = 0; - c_start = clock(); + c0 = clock(); cy0 = cyclecount(); do { - j->run(p); - ii++; + for (k = 0; k < o.k; k++) { j->run(p); } + ii += k; gettimeofday(&tv_now, 0); } while (TV_CMP(&tv_now, <, &tv_next)); - c_stop = clock(); - t = (double)(c_stop - c_start)/CLOCKS_PER_SEC; - itot += ii; - ttot += t; - printf("%5u: did = %5lu; /sec = %5f; avg /sec = %5f\n", + cy1 = cyclecount(); c1 = clock(); + t = (double)(c1 - c0)/CLOCKS_PER_SEC; + itot += ii; ttot += t; + printf("%5u: did = %5lu; /sec = %5f; avg /sec = %5f", n, ii, ii/t, itot/ttot); + if (cyclecount_active_p) { + SUB64(cydiff, cy1, cy0); cy = LO64(cydiff) + ldexp(HI64(cydiff), 32); + cytot += cy; + printf(" (cy/%s = %3f; avg cy/%s = %3f)", + o.opwhat, cy/ii/o.sc, o.opwhat, cytot/itot/o.sc); + } + putchar('\n'); fflush(stdout); n++; } while (!o.i || n < o.i); diff --git a/pub/dh-param.c b/pub/dh-param.c index b593fb8c..69e24376 100644 --- a/pub/dh-param.c +++ b/pub/dh-param.c @@ -126,7 +126,7 @@ int main(int argc, char *argv[]) group *g; dh_infofromdata(&dp, pe->data); g = group_prime(&dp); - if (mp_bits(dp.p) > 2048 && + if (mp_bits(dp.p) > 3072 && (!argv[1] || strcmp(argv[1], "keen") != 0)) { printf(" [%s skipped]", pe->name); fflush(stdout); diff --git a/symm/.gitignore b/symm/.gitignore index 55e2c173..5c18b126 100644 --- a/symm/.gitignore +++ b/symm/.gitignore @@ -1 +1,69 @@ -modes/ +/modes/ +/modes.am +/stubs.am +/stubs.gen-stamp + +/t/salsa20 +/t/sha3 + +/sha224.c +/sha224.h +/sha384.h +/sha384.c +/sha512-224.c +/sha512-224.h +/sha512-256.c +/sha512-256.h + +/safersk.c +/safersk.h + +/whirlpool256.c +/whirlpool256.h + +/sha3-224.c +/sha3-224.h +/sha3-256.c +/sha3-256.h +/sha3-384.c +/sha3-384.h +/sha3-512.c +/sha3-512.h +/kmac128.h +/kmac256.h +/shake128.h +/shake256.h +/shake128-xof.h +/shake256-xof.h + +/chacha20.h +/chacha12.h +/chacha8.h +/chacha12-ietf.h +/chacha20-ietf.h +/chacha8-ietf.h +/xchacha.h +/xchacha20.h +/xchacha12.h +/xchacha8.h +/chacha20-naclbox.h +/chacha12-naclbox.h +/chacha8-naclbox.h +/chacha20-poly1305.h +/chacha12-poly1305.h +/chacha8-poly1305.h + +/salsa2012.h +/salsa208.h +/salsa20-ietf.h +/salsa2012-ietf.h +/salsa208-ietf.h +/xsalsa20.h +/xsalsa2012.h +/xsalsa208.h +/salsa20-naclbox.h +/salsa2012-naclbox.h +/salsa208-naclbox.h +/salsa20-poly1305.h +/salsa2012-poly1305.h +/salsa208-poly1305.h diff --git a/symm/Makefile.am b/symm/Makefile.am index 0e56319d..2a43f077 100644 --- a/symm/Makefile.am +++ b/symm/Makefile.am @@ -32,6 +32,11 @@ nodist_libsymm_la_SOURCES = TEST_LIBS = libsymm.la +noinst_LTLIBRARIES += libsymmtest.la +libsymmtest_la_SOURCES = +libsymmtest_la_CFLAGS = $(AM_CFLAGS) -DSRCDIR=\"$(srcdir)\" +TEST_LIBS += libsymmtest.la + VPATH += $(srcdir)/modes ###-------------------------------------------------------------------------- @@ -63,6 +68,8 @@ $(srcdir)/modes.am: modes.am.in Makefile.am blkc="$(BLKCS)" \ blkcmode="$(BLKCMODES)" \ blkcciphermode="$(BLKCCIPHERMODES)" \ + blkcaeadmode="$(BLKCAEADMODES)" \ + blkcmacmode="$(BLKCMACMODES)" \ hash="$(HASHES)" \ hashmode="$(HASHMODES)" \ hashciphermode="$(HASHCIPHERMODES)" \ @@ -73,6 +80,7 @@ $(srcdir)/stubs.am: stubs.am.in Makefile.am ## Initialize lists of known classes. ALL_CIPHERS = $(CIPHER_MODES) +ALL_AEADS = $(AEAD_MODES) ALL_HASHES = $(HASHES) ALL_MACS = $(MAC_MODES) @@ -89,6 +97,12 @@ BLKCMODES = BLKCCIPHERMODES = BLKCMODES += $(BLKCCIPHERMODES) +BLKCAEADMODES = +BLKCMODES += $(BLKCAEADMODES) + +BLKCMACMODES = +BLKCMODES += $(BLKCMACMODES) + ## A tool for translating the AES-contest test vectors into a form our test ## rigs understand. EXTRA_DIST += aes-trans @@ -119,13 +133,14 @@ endif BLKCS += cast128 cast256 libsymm_la_SOURCES += cast-s.c cast-sk.c cast-base.h cast256.log: t/cast256 -EXTRA_DIST += t/cast256.aes +EXTRA_DIST += t/cast256.aes t/cast256.local MAINTAINERCLEANFILES += $(srcdir)/t/cast256 -t/cast256: t/cast256.aes - $(AM_V_GEN)$(srcdir)/aes-trans CAST256 \ - <$(srcdir)/t/cast256.aes \ - >$(srcdir)/t/cast256.new && \ - mv $(srcdir)/t/cast256.new $(srcdir)/t/cast256 +t/cast256: t/cast256.aes t/cast256.local + $(AM_V_GEN)cd $(srcdir) && \ + { ./aes-trans CAST256 t/cast256.new && \ + mv t/cast256.new t/cast256 ## IBM's `DES' block cipher, by Feistel, Coppersmith, and others. BLKCS += des des3 @@ -161,13 +176,14 @@ $(precomp)/symm/mars-tab.c: mv $(precomp)/symm/mars-tab.c.new $(precomp)/symm/mars-tab.c endif mars.log: t/mars -EXTRA_DIST += t/mars.aes +EXTRA_DIST += t/mars.aes t/mars.local MAINTAINERCLEANFILES += $(srcdir)/t/mars -t/mars: t/mars.aes - $(AM_V_GEN)$(srcdir)/aes-trans Mars \ - <$(srcdir)/t/mars.aes \ - >$(srcdir)/t/mars.new && \ - mv $(srcdir)/t/mars.new $(srcdir)/t/mars +t/mars: t/mars.aes t/mars.local + $(AM_V_GEN)cd $(srcdir) && \ + { ./aes-trans Mars t/mars.new && \ + mv t/mars.new t/mars ## Daemen, Peeters, Van Assche and Rijmen's `Noekeon'. BLKCS += noekeon @@ -208,13 +224,14 @@ $(precomp)/symm/rijndael-tab.c: $(precomp)/symm/rijndael-tab.c endif rijndael.log: t/rijndael -EXTRA_DIST += t/rijndael.aes +EXTRA_DIST += t/rijndael.aes t/rijndael.local MAINTAINERCLEANFILES += $(srcdir)/t/rijndael -t/rijndael: t/rijndael.aes - $(AM_V_GEN)$(srcdir)/aes-trans Rijndael \ - <$(srcdir)/t/rijndael.aes \ - >$(srcdir)/t/rijndael.new && \ - mv $(srcdir)/t/rijndael.new $(srcdir)/t/rijndael +t/rijndael: t/rijndael.aes t/rijndael.local + $(AM_V_GEN)cd $(srcdir) && \ + { ./aes-trans Rijndael t/rijndael.new && \ + mv t/rijndael.new t/rijndael ## Massey's `SAFER' block ciphers. BLKCS += safer safersk @@ -238,13 +255,14 @@ libsymm_la_SOURCES += serpent-sbox.h check_PROGRAMS += serpent-check TESTS += serpent-check serpent.log: t/serpent -EXTRA_DIST += t/serpent.aes +EXTRA_DIST += t/serpent.aes t/serpent.local MAINTAINERCLEANFILES += $(srcdir)/t/serpent -t/serpent: t/serpent.aes - $(AM_V_GEN)$(srcdir)/aes-trans Serpent -v rev=1 \ - <$(srcdir)/t/serpent.aes \ - >$(srcdir)/t/serpent.new && \ - mv $(srcdir)/t/serpent.new $(srcdir)/t/serpent +t/serpent: t/serpent.aes t/serpent.local + $(AM_V_GEN)cd $(srcdir) && \ + { ./aes-trans Serpent -v rev=1 t/serpent.new && \ + mv t/serpent.new t/serpent ## The National Security Agency's `Skipjack' block cipher. You don't want to ## use this. @@ -283,13 +301,14 @@ $(precomp)/symm/twofish-tab.c: $(precomp)/symm/twofish-tab.c endif twofish.log: t/twofish -EXTRA_DIST += t/twofish.aes +EXTRA_DIST += t/twofish.aes t/twofish.local MAINTAINERCLEANFILES += $(srcdir)/t/twofish -t/twofish: t/twofish.aes - $(AM_V_GEN)$(srcdir)/aes-trans Twofish \ - <$(srcdir)/t/twofish.aes \ - >$(srcdir)/t/twofish.new && \ - mv $(srcdir)/t/twofish.new $(srcdir)/t/twofish +t/twofish: t/twofish.aes t/twofish.local + $(AM_V_GEN)cd $(srcdir) && \ + { ./aes-trans Twofish t/twofish.new && \ + mv t/twofish.new t/twofish ## The old NIST modes for DES. BLKCCIPHERMODES += cbc cfb ecb ofb @@ -297,6 +316,29 @@ BLKCCIPHERMODES += cbc cfb ecb ofb ## Counter mode. BLKCCIPHERMODES += counter +## CMAC mode. +BLKCMACMODES += cmac pmac1 + +## Various AEAD modes. +pkginclude_HEADERS += ocb.h +BLKCAEADMODES += ccm eax gcm ocb1 ocb3 +libsymm_la_SOURCES += ccm.c gcm.c ocb.c +if CPUFAM_X86 +libsymm_la_SOURCES += gcm-x86ish-pclmul.S +endif +if CPUFAM_AMD64 +libsymm_la_SOURCES += gcm-x86ish-pclmul.S +endif +if CPUFAM_ARMEL +libsymm_la_SOURCES += gcm-arm-crypto.S +endif +if CPUFAM_ARM64 +libsymm_la_SOURCES += gcm-arm64-pmull.S +endif + +TESTS += gcm.t$(EXEEXT) +EXTRA_DIST += t/gcm + ###-------------------------------------------------------------------------- ### Hash functions. @@ -554,6 +596,32 @@ poly1305_p11_t_CPPFLAGS += -DPOLY1305_IMPL=11 poly1305_p11_t_LDADD = $(TEST_LIBS) $(top_builddir)/libcatacomb.la poly1305_p11_t_LDADD += $(mLib_LIBS) $(CATACOMB_LIBS) $(LIBS) +## Combining Salsa20/ChaCha with Poly1305. +pkginclude_HEADERS += latinpoly.h latinpoly-def.h +libsymm_la_SOURCES += latinpoly.c chacha-poly1305.c salsa20-poly1305.c +libsymmtest_la_SOURCES += latinpoly-test.c latinpoly-test.h + +ALL_AEADS += chacha20-poly1305 salsa20-poly1305 +ALL_AEADS += chacha12-poly1305 salsa2012-poly1305 +ALL_AEADS += chacha8-poly1305 salsa208-poly1305 +ALL_AEADS += chacha20-naclbox salsa20-naclbox +ALL_AEADS += chacha12-naclbox salsa2012-naclbox +ALL_AEADS += chacha8-naclbox salsa208-naclbox +STUBS_HDR += ChaCha20-Poly1305,chacha20-poly1305,latinpoly +STUBS_HDR += ChaCha12-Poly1305,chacha12-poly1305,latinpoly +STUBS_HDR += ChaCha8-Poly1305,chacha8-poly1305,latinpoly +STUBS_HDR += Salsa20-Poly1305,salsa20-poly1305,latinpoly +STUBS_HDR += Salsa20/12-Poly1305,salsa2012-poly1305,latinpoly +STUBS_HDR += Salsa20/8-Poly1305,salsa208-poly1305,latinpoly +STUBS_HDR += ChaCha20-NaClBox,chacha20-naclbox,latinpoly +STUBS_HDR += ChaCha12-NaClBox,chacha12-naclbox,latinpoly +STUBS_HDR += ChaCha8-NaClBox,chacha8-naclbox,latinpoly +STUBS_HDR += Salsa20-NaClBox,salsa20-naclbox,latinpoly +STUBS_HDR += Salsa20/12-NaClBox,salsa2012-naclbox,latinpoly +STUBS_HDR += Salsa20/8-NaClBox,salsa208-naclbox,latinpoly +TESTS += chacha-poly1305.t$(EXEEXT) +TESTS += salsa20-poly1305.t$(EXEEXT) + ###-------------------------------------------------------------------------- ### Autogenerated mode implementations. @@ -592,6 +660,9 @@ MAINTAINERCLEANFILES += $(GENMODES_H) pkginclude_HEADERS += $(GENMODES_H) $(GENMODES_H): modes/gen-stamp +## Additional test machinery. +libsymmtest_la_SOURCES += modes-test.c modes-test.h + ###-------------------------------------------------------------------------- ### Autogenerated stub headers. @@ -627,6 +698,15 @@ gciphertab.c: gthingtab.c.in Makefile.am $(AM_V_GEN)$(multigen) -g $(srcdir)/gthingtab.c.in gciphertab.c \ what=gcipher cls=gccipher thing="$(ALL_CIPHERS)" +## Table of AEAD classes. +pkginclude_HEADERS += gaead.h +CLEANFILES += gaeadtab.c +libsymm_la_SOURCES += gaead.c +nodist_libsymm_la_SOURCES += gaeadtab.c +gaeadtab.c: gthingtab.c.in Makefile.am + $(AM_V_GEN)$(multigen) -g $(srcdir)/gthingtab.c.in gaeadtab.c \ + what=gaead cls=gcaead thing="$(ALL_AEADS)" + ## Table of hash classes. pkginclude_HEADERS += ghash.h ghash-def.h CLEANFILES += ghashtab.c @@ -649,9 +729,13 @@ gmactab.c: gthingtab.c.in Makefile.am ## Run the test programs. TESTS += $(SYMM_TESTS) EXTRA_DIST += $(SYMM_TEST_FILES) +EXTRA_DIST += $(REGRESSION_TEST_FILES) -## A piece of sample text for round-trip testing encryption modes. -EXTRA_DIST += daftstory.h +t/modes/%.regress: + $(MAKE) modes/$*.t && \ + mkdir -p $(srcdir)/t/modes/ && \ + modes/$*.t -o$(srcdir)/$@.new && \ + mv $(srcdir)/$@.new $(srcdir)/$@ ## Clean the debris from the `modes' subdirectory. CLEANFILES += modes/*.to modes/*.t$(EXEEXT) diff --git a/symm/blkc.h b/symm/blkc.h index ff631f09..bbba7631 100644 --- a/symm/blkc.h +++ b/symm/blkc.h @@ -69,6 +69,8 @@ #define BLKC_STORE_E(PRE) BLKC_GLUE(STORE32_, BLKC_ENDIAN(PRE)) #define BLKC_LOAD_E(PRE) BLKC_GLUE(LOAD32_, BLKC_ENDIAN(PRE)) +#define BLKC_ID(x) (x) + /* --- Interface macros --- */ #define BLKC_STORE(PRE, b, w) \ @@ -95,24 +97,62 @@ BLKC_GLUE(BLKC_XMOVE_, BLKC_TYPE(PRE)) \ (PRE, w, wx, BLKC_BITS(PRE)) -#define BLKC_STEP(PRE, w) \ - BLKC_GLUE(BLKC_STEP_X_, BLKC_ENDIAN(PRE)) \ - (PRE, w) +#define BLKC_BSTEP(PRE, w) BLKC_BADD(PRE, w, 1) +#define BLKC_LSTEP(PRE, w) BLKC_LADD(PRE, w, 1) +#define BLKC_STEP(PRE, w) BLKC_ADD(PRE, w, 1) + +#define BLKC_BADD(PRE, w, n) \ + BLKC_GLUE(BLKC_BADD_X_, BLKC_ENDIAN(PRE)) \ + (PRE, w, n) +#define BLKC_LADD(PRE, w, n) \ + BLKC_GLUE(BLKC_LADD_X_, BLKC_ENDIAN(PRE)) \ + (PRE, w, n) +#define BLKC_ADD(PRE, w, n) \ + BLKC_GLUE(BLKC_ADD_X_, BLKC_ENDIAN(PRE)) \ + (PRE, BLKC_ID, w, n) #define BLKC_ZERO(PRE, w) \ BLKC_GLUE(BLKC_ZERO_, BLKC_TYPE(PRE)) \ (PRE, w, BLKC_BITS(PRE)) +#define BLKC_BSET(PRE, w, x) \ + BLKC_GLUE(BLKC_BSET_X_, BLKC_ENDIAN(PRE)) \ + (PRE, w, x) +#define BLKC_LSET(PRE, w, x) \ + BLKC_GLUE(BLKC_LSET_X_, BLKC_ENDIAN(PRE)) \ + (PRE, w, x) #define BLKC_SET(PRE, w, x) \ BLKC_GLUE(BLKC_SET_X_, BLKC_ENDIAN(PRE)) \ - (PRE, w, x) + (PRE, BLKC_ID, w, x) + +#define BLKC_BWORD(PRE, x) BLKC_GLUE(BLKC_BWORD_, BLKC_ENDIAN(PRE))(x) +#define BLKC_LWORD(PRE, x) BLKC_GLUE(BLKC_LWORD_, BLKC_ENDIAN(PRE))(x) #define BLKC_SHOW(PRE, tag, w) do { \ fputs(tag ": ", stdout); \ - BLKC_SKEL_X(PRE, BLKC_W(w);, printf("%08x ", *_w++);); \ + BLKC_SKEL_X(PRE, const BLKC_W(w);, \ + { printf("%08x ", BLKC_BWORD(PRE, *_w)); _w++; }); \ fputc('\n', stdout); \ } while (0) +/* --- Utilities --- * + * + * These seem too hard to properly generalize, or I'd have put them in + * . + */ + +#ifdef HAVE_UINT64 +# define BLKC_ADDC32(op, z_out, c_out, x, y) do { \ + uint64 _t = (uint64)op(x) + (y); \ + (z_out) = U32(op(_t)); (c_out) = _t >> 32; \ + } while (0) +#else +# define BLKC_ADDC32(op, z_out, c_out, x, y) do { \ + uint32 _x = op(x), _c = 0, _t; \ + _t = U32(_x + (y)); (z_out) = op(_t); (c_out) = (_t < _x); \ + } while (0) +#endif + /* --- General implementation skeleton --- */ #define BLKC_SKEL(PRE, decl, guts) do { \ @@ -120,15 +160,15 @@ guts \ } while (0) -#define BLKC_P(p) register octet *_p = (octet *)(p) -#define BLKC_W(w) register uint32 *_w = (w) -#define BLKC_WX(wx) register uint32 *_wx = (wx) +#define BLKC_P(p) octet *_p = (octet *)(p) +#define BLKC_W(w) uint32 *_w = (w) +#define BLKC_WX(wx) uint32 *_wx = (wx) /* --- Implementation for unusual block sizes --- */ #define BLKC_SKEL_X(PRE, decl, guts) \ BLKC_SKEL(PRE, unsigned _i; decl, \ - for (_i = 0; _i < PRE##_BLKSZ / 4; _i++) { \ + for (_i = 0; _i < PRE##_BLKSZ/4; _i++) { \ guts \ }) @@ -159,33 +199,48 @@ #define BLKC_ZERO_X(PRE, w, n) \ BLKC_SKEL_X(PRE, BLKC_W(w);, *_w++ = 0;) -#define BLKC_STEP_X_B(PRE, w) do { \ - unsigned _i = PRE##_BLKSZ / 4; BLKC_W(w); uint32 _x = 0; \ - while (_i && !_x) { _i--; _w[_i] = _x = U32(_w[_i] + 1); } \ +#define BLKC_BADD_X_B(PRE, w, n) BLKC_ADD_X_B(PRE, BLKC_ID, w, n) +#define BLKC_BADD_X_L(PRE, w, n) BLKC_ADD_X_B(PRE, ENDSWAP32, w, n) +#define BLKC_LADD_X_B(PRE, w, n) BLKC_ADD_X_L(PRE, ENDSWAP32, w, n) +#define BLKC_LADD_X_L(PRE, w, n) BLKC_ADD_X_L(PRE, BLKC_ID, w, n) + +#define BLKC_ADD_X_B(PRE, op, w, n) do { \ + unsigned _i = PRE##_BLKSZ/4; BLKC_W(w); uint32 _n = (n); \ + while (_i-- && _n) BLKC_ADDC32(op, _w[_i], _n, _w[_i], _n); \ } while (0) -#define BLKC_STEP_X_L(PRE, w) do { \ - unsigned _i = 0; BLKC_W(w); uint32 _x = 0; \ - while (_i < PRE##_BLKSZ / 4 && !_x) \ - { _w[_i] = _x = U32(_w[_i] + 1); _i++; } \ +#define BLKC_ADD_X_L(PRE, op, w, n) do { \ + unsigned _i = 0; BLKC_W(w); uint32 _n = (n); \ + while (_i < PRE##_BLKSZ/4 && _n) \ + { BLKC_ADDC32(op, _w[_i], _n, _w[_i], _n); _i++; } \ } while (0) -#define BLKC_SET_X_B(PRE, w, x) do { \ - unsigned _i; BLKC_W(w); unsigned long _x = x; \ - for (_i = 0; _i < PRE##_BLKSZ / 4; _i++) { \ - *_w++ = U32(_x); \ +#define BLKC_BSET_X_B(PRE, w, x) BLKC_SET_X_B(PRE, BLKC_ID, w, x) +#define BLKC_BSET_X_L(PRE, w, x) BLKC_SET_X_B(PRE, ENDSWAP32, w, x) +#define BLKC_LSET_X_B(PRE, w, x) BLKC_SET_X_L(PRE, ENDSWAP32, w, x) +#define BLKC_LSET_X_L(PRE, w, x) BLKC_SET_X_L(PRE, BLKC_ID, w, x) + +#define BLKC_SET_X_B(PRE, op, w, x) do { \ + unsigned _i; BLKC_W(w); unsigned long _x = x; _w += PRE##_BLKSZ/4; \ + for (_i = 0; _i < PRE##_BLKSZ/4; _i++) { \ + *--_w = U32(op(_x)); \ _x = ((_x & ~(unsigned long)MASK32) >> 16) >> 16; \ } \ } while (0) -#define BLKC_SET_X_L(PRE, w, x) do { \ - unsigned _i; BLKC_W(w); unsigned long _x = x; _w += PRE##_BLKSZ / 4; \ - for (_i = 0; _i < PRE##_BLKSZ / 4; _i++) { \ - *--_w = U32(_x); \ +#define BLKC_SET_X_L(PRE, op, w, x) do { \ + unsigned _i; BLKC_W(w); unsigned long _x = x; \ + for (_i = 0; _i < PRE##_BLKSZ/4; _i++) { \ + *_w++ = U32(op(_x)); \ _x = ((_x & ~(unsigned long)MASK32) >> 16) >> 16; \ } \ } while (0) +#define BLKC_BWORD_B(x) (x) +#define BLKC_BWORD_L(x) ENDSWAP32(x) +#define BLKC_LWORD_B(x) ENDSWAP32(x) +#define BLKC_LWORD_L(x) (x) + /* --- Implementation for known block sizes --- */ #define BLKC_SKEL_64(PRE, decl, op, guts) \ @@ -244,6 +299,94 @@ BLKC_GLUE(BLKC_SKEL_, n) \ (PRE, BLKC_W(w); const BLKC_WX(wx);, op, BLKC_XMOVE_GUTS) +/*----- Binary field arithmetic -------------------------------------------*/ + +#define BLKC_POLY_IRRED64 0x001b +#define BLKC_POLY_IRRED96 0x0641 +#define BLKC_POLY_IRRED128 0x0087 +#define BLKC_POLY_IRRED192 0x0087 +#define BLKC_POLY_IRRED256 0x0425 + +#define BLKC_POLY_PRIM64 0x001b +#define BLKC_POLY_PRIM96 0x0641 +#define BLKC_POLY_PRIM128 0x0087 +#define BLKC_POLY_PRIM192 0x8821 +#define BLKC_POLY_PRIM256 0x0425 + +#define BLKC_POLY(PRE, f) BLKC_GLUE(BLKC_POLY_##f, BLKC_BITS(PRE)) + +#define BLKC_BLSHIFT(PRE, f, z, x) \ + BLKC_GLUE(BLKC_BLSHIFT_X_, BLKC_ENDIAN(PRE)) \ + (PRE, f, z, x) +#define BLKC_LLSHIFT(PRE, f, z, x) \ + BLKC_GLUE(BLKC_LLSHIFT_X_, BLKC_ENDIAN(PRE)) \ + (PRE, f, z, x) +#define BLKC_LSHIFT(PRE, f, z, x) \ + BLKC_GLUE(BLKC_LSHIFT_X_, BLKC_ENDIAN(PRE)) \ + (PRE, BLKC_ID, f, z, x) + +#define BLKC_BRSHIFT(PRE, f, z, x) \ + BLKC_GLUE(BLKC_BRSHIFT_X_, BLKC_ENDIAN(PRE)) \ + (PRE, f, z, x) +#define BLKC_LRSHIFT(PRE, f, z, x) \ + BLKC_GLUE(BLKC_LRSHIFT_X_, BLKC_ENDIAN(PRE)) \ + (PRE, f, z, x) +#define BLKC_RSHIFT(PRE, f, z, x) \ + BLKC_GLUE(BLKC_RSHIFT_X_, BLKC_ENDIAN(PRE)) \ + (PRE, BLKC_ID, f, z, x) + +#define BLKC_BLSHIFT_X_B(PRE, f, z, x) BLKC_LSHIFT_X_B(PRE, BLKC_ID, f, z, x) +#define BLKC_LLSHIFT_X_B(PRE, f, z, x) BLKC_LSHIFT_X_L(PRE, ENDSWAP32, f, z, x) +#define BLKC_BLSHIFT_X_L(PRE, f, z, x) BLKC_LSHIFT_X_B(PRE, ENDSWAP32, f, z, x) +#define BLKC_LLSHIFT_X_L(PRE, f, z, x) BLKC_LSHIFT_X_L(PRE, BLKC_ID, f, z, x) + +#define BLKC_BRSHIFT_X_B(PRE, f, z, x) BLKC_RSHIFT_X_B(PRE, BLKC_ID, f, z, x) +#define BLKC_LRSHIFT_X_B(PRE, f, z, x) BLKC_RSHIFT_X_L(PRE, ENDSWAP32, f, z, x) +#define BLKC_BRSHIFT_X_L(PRE, f, z, x) BLKC_RSHIFT_X_B(PRE, ENDSWAP32, f, z, x) +#define BLKC_LRSHIFT_X_L(PRE, f, z, x) BLKC_RSHIFT_X_L(PRE, BLKC_ID, f, z, x) + +#define BLKC_LSHIFT_X_B(PRE, op, f, z, x) do { \ + uint32 *_z = (z); const uint32 *_x = (x); \ + uint32 _t = op(_x[0]), _m = -(uint32)((_t >> 31)&1u), \ + _c = BLKC_POLY(PRE, f)&_m; \ + unsigned _i; \ + \ + for (_i = PRE##_BLKSZ/4; _i-- > 0; ) \ + { _t = op(_x[_i]); _z[_i] = op((_t << 1) ^ _c); _c = (_t >> 31)&1u; } \ +} while (0) + +#define BLKC_RSHIFT_X_B(PRE, op, f, z, x) do { \ + uint32 *_z = (z); const uint32 *_x = (x); \ + uint32 _t, _t0 = op(_x[PRE##_BLKSZ/4 - 1]), _m = -(uint32)(_t0&1u), \ + _c = 0x80000000&_m; \ + unsigned _i; \ + \ + for (_i = 0; _i < PRE##_BLKSZ/4 - 1; _i++) \ + { _t = op(_x[_i]); _z[_i] = op((_t >> 1) ^ _c); _c = (_t&1u) << 31; } \ + _t0 ^= BLKC_POLY(PRE, f)&_m; _z[PRE##_BLKSZ/4 - 1] = op((_t0 >> 1) ^ _c); \ +} while (0) + +#define BLKC_LSHIFT_X_L(PRE, op, f, z, x) do { \ + uint32 *_z = (z); const uint32 *_x = (x); \ + uint32 _t = op(_x[PRE##_BLKSZ/4 - 1]), _m = -(uint32)((_t >> 31)&1u), \ + _c = BLKC_POLY(PRE, f)&_m; \ + unsigned _i; \ + \ + for (_i = 0; _i < PRE##_BLKSZ/4; _i++) \ + { _t = op(_x[_i]); _z[_i] = op((_t << 1) ^ _c); _c = (_t >> 31)&1u; } \ +} while (0) + +#define BLKC_RSHIFT_X_L(PRE, op, f, z, x) do { \ + uint32 *_z = (z); const uint32 *_x = (x); \ + uint32 _t, _t0 = op(_x[0]), _m = -(uint32)(_t0&1u), \ + _c = 0x80000000&_m; \ + unsigned _i; \ + \ + for (_i = PRE##_BLKSZ/4 - 1; _i-- > 1; ) \ + { _t = op(_x[_i]); _z[_i] = op((_t >> 1) ^ _c); _c = (_t&1u) << 31; } \ + _t0 ^= BLKC_POLY(PRE, f)&_m; _z[0] = op((_t0 >> 1) ^ _c); \ +} while (0) + /*----- Test rig for block ciphers ----------------------------------------*/ /* --- @BLKC_TEST@ --- * @@ -267,9 +410,9 @@ static int pre##_verify(dstr *v) \ { \ pre##_ctx k; \ - uint32 p[PRE##_BLKSZ / 4]; \ - uint32 c[PRE##_BLKSZ / 4]; \ - uint32 d[PRE##_BLKSZ / 4]; \ + uint32 p[PRE##_BLKSZ/4]; \ + uint32 c[PRE##_BLKSZ/4]; \ + uint32 d[PRE##_BLKSZ/4]; \ dstr b = DSTR_INIT; \ int ok = 1; \ \ diff --git a/symm/cbc-def.h b/symm/cbc-def.h index 907a5dba..480f5796 100644 --- a/symm/cbc-def.h +++ b/symm/cbc-def.h @@ -81,9 +81,7 @@ */ \ \ void pre##_cbcgetiv(const pre##_cbcctx *ctx, void *iv) \ -{ \ - BLKC_STORE(PRE, iv, ctx->iv); \ -} \ + { BLKC_STORE(PRE, iv, ctx->a); } \ \ /* --- @pre_cbcsetiv@ --- * \ * \ @@ -96,9 +94,7 @@ void pre##_cbcgetiv(const pre##_cbcctx *ctx, void *iv) \ */ \ \ void pre##_cbcsetiv(pre##_cbcctx *ctx, const void *iv) \ -{ \ - BLKC_LOAD(PRE, ctx->iv, iv); \ -} \ + { BLKC_LOAD(PRE, ctx->a, iv); } \ \ /* --- @pre_cbcsetkey@ --- * \ * \ @@ -111,9 +107,7 @@ void pre##_cbcsetiv(pre##_cbcctx *ctx, const void *iv) \ */ \ \ void pre##_cbcsetkey(pre##_cbcctx *ctx, const pre##_ctx *k) \ -{ \ - ctx->ctx = *k; \ -} \ + { ctx->ctx = *k; } \ \ /* --- @pre_cbcinit@ --- * \ * \ @@ -131,12 +125,13 @@ void pre##_cbcsetkey(pre##_cbcctx *ctx, const pre##_ctx *k) \ */ \ \ void pre##_cbcinit(pre##_cbcctx *ctx, \ - const void *key, size_t sz, \ - const void *iv) \ + const void *key, size_t sz, \ + const void *iv) \ { \ static const octet zero[PRE##_BLKSZ] = { 0 }; \ + \ pre##_init(&ctx->ctx, key, sz); \ - BLKC_LOAD(PRE, ctx->iv, iv ? iv : zero); \ + BLKC_LOAD(PRE, ctx->a, iv ? iv : zero); \ } \ \ /* --- @pre_cbcencrypt@ --- * \ @@ -155,16 +150,18 @@ void pre##_cbcinit(pre##_cbcctx *ctx, \ */ \ \ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ - const void *src, void *dest, \ - size_t sz) \ + const void *src, void *dest, \ + size_t sz) \ { \ const octet *s = src; \ octet *d = dest; \ + octet b[PRE##_BLKSZ], bb[PRE##_BLKSZ]; \ + octet y; \ + unsigned i; \ \ /* --- Empty blocks are trivial --- */ \ \ - if (!sz) \ - return; \ + if (!sz) return; \ \ /* --- Extra magical case for a short block --- * \ * \ @@ -174,18 +171,13 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ */ \ \ if (sz < PRE##_BLKSZ) { \ - octet b[PRE##_BLKSZ]; \ - unsigned i; \ - \ - pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv); \ - BLKC_STORE(PRE, b, ctx->iv); \ - if (d) { \ - for (i = 0; i < sz; i++) \ - d[i] = b[i] ^ (s ? s[i] : 0); \ - } \ + pre##_eblk(&ctx->ctx, ctx->a, ctx->a); \ + BLKC_STORE(PRE, b, ctx->a); \ + if (!d) d = bb; \ + for (i = 0; i < sz; i++) d[i] = b[i] ^ (s ? s[i] : 0); \ memmove(b, b + sz, PRE##_BLKSZ - sz); \ memcpy(b + PRE##_BLKSZ - sz, d, sz); \ - BLKC_LOAD(PRE, ctx->iv, b); \ + BLKC_LOAD(PRE, ctx->a, b); \ return; \ } \ \ @@ -196,16 +188,10 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ * and keep a copy of the ciphertext for the next block. \ */ \ \ - while (sz >= 2 * PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ - if (s) { \ - BLKC_XLOAD(PRE, ctx->iv, s); \ - s += PRE##_BLKSZ; \ - } \ - pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv); \ - if (d) { \ - BLKC_STORE(PRE, d, ctx->iv); \ - d += PRE##_BLKSZ; \ - } \ + while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ + if (s) { BLKC_XLOAD(PRE, ctx->a, s); s += PRE##_BLKSZ; } \ + pre##_eblk(&ctx->ctx, ctx->a, ctx->a); \ + if (d) { BLKC_STORE(PRE, d, ctx->a); d += PRE##_BLKSZ; } \ sz -= PRE##_BLKSZ; \ } \ \ @@ -215,8 +201,6 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ */ \ \ if (sz) { \ - octet b[PRE##_BLKSZ]; \ - unsigned i; \ \ /* --- Let @sz@ be the size of the partial block --- */ \ \ @@ -230,9 +214,9 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ * block. \ */ \ \ - if (s) BLKC_XLOAD(PRE, ctx->iv, s); \ - pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv); \ - BLKC_STORE(PRE, b, ctx->iv); \ + if (s) BLKC_XLOAD(PRE, ctx->a, s); \ + pre##_eblk(&ctx->ctx, ctx->a, ctx->a); \ + BLKC_STORE(PRE, b, ctx->a); \ \ /* --- Second stage --- * \ * \ @@ -244,13 +228,13 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ if (s) s += PRE##_BLKSZ; \ if (d) d += PRE##_BLKSZ; \ for (i = 0; i < sz; i++) { \ - register octet x = b[i]; \ + y = b[i]; \ if (s) b[i] ^= s[i]; \ - if (d) d[i] = x; \ + if (d) d[i] = y; \ } \ - BLKC_LOAD(PRE, ctx->iv, b); \ - pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv); \ - if (d) BLKC_STORE(PRE, d - PRE##_BLKSZ, ctx->iv); \ + BLKC_LOAD(PRE, ctx->a, b); \ + pre##_eblk(&ctx->ctx, ctx->a, ctx->a); \ + if (d) BLKC_STORE(PRE, d - PRE##_BLKSZ, ctx->a); \ } \ \ /* --- Done --- */ \ @@ -274,16 +258,19 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ */ \ \ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ - const void *src, void *dest, \ - size_t sz) \ + const void *src, void *dest, \ + size_t sz) \ { \ const octet *s = src; \ octet *d = dest; \ + uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ/4]; \ + octet b[PRE##_BLKSZ], c[PRE##_BLKSZ]; \ + octet y; \ + unsigned i; \ \ /* --- Empty blocks are trivial --- */ \ \ - if (!sz) \ - return; \ + if (!sz) return; \ \ /* --- Extra magical case for a short block --- * \ * \ @@ -293,19 +280,12 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ */ \ \ if (sz < PRE##_BLKSZ) { \ - octet b[PRE##_BLKSZ], c[PRE##_BLKSZ]; \ - unsigned i; \ - \ - pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv); \ - BLKC_STORE(PRE, b, ctx->iv); \ - for (i = 0; i < sz; i++) { \ - register octet x = s[i]; \ - d[i] = b[i] ^ x; \ - c[i] = x; \ - } \ + pre##_eblk(&ctx->ctx, ctx->a, ctx->a); \ + BLKC_STORE(PRE, b, ctx->a); \ + for (i = 0; i < sz; i++) { y = s[i]; d[i] = b[i] ^ y; c[i] = y; } \ memmove(b, b + sz, PRE##_BLKSZ - sz); \ memcpy(b + PRE##_BLKSZ - sz, c, sz); \ - BLKC_LOAD(PRE, ctx->iv, b); \ + BLKC_LOAD(PRE, ctx->a, b); \ return; \ } \ \ @@ -316,14 +296,11 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ * and keep a copy of the ciphertext for the next block. \ */ \ \ - while (sz >= 2 * PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ - uint32 b[PRE##_BLKSZ / 4], niv[PRE##_BLKSZ / 4]; \ - BLKC_LOAD(PRE, niv, s); \ - pre##_dblk(&ctx->ctx, niv, b); \ - BLKC_XSTORE(PRE, d, b, ctx->iv); \ - BLKC_MOVE(PRE, ctx->iv, niv); \ - s += PRE##_BLKSZ; \ - d += PRE##_BLKSZ; \ + while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ + BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ; \ + pre##_dblk(&ctx->ctx, t, u); \ + BLKC_XSTORE(PRE, d, u, ctx->a); d += PRE##_BLKSZ; \ + BLKC_MOVE(PRE, ctx->a, t); \ sz -= PRE##_BLKSZ; \ } \ \ @@ -333,9 +310,6 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ */ \ \ if (sz) { \ - octet b[PRE##_BLKSZ]; \ - uint32 bk[PRE##_BLKSZ / 4], niv[PRE##_BLKSZ / 4]; \ - unsigned i; \ \ /* --- Let @sz@ be the size of the partial block --- */ \ \ @@ -347,8 +321,8 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ * is carried over for the next encryption operation. \ */ \ \ - BLKC_LOAD(PRE, niv, s); \ - pre##_dblk(&ctx->ctx, niv, bk); \ + BLKC_LOAD(PRE, t, s); \ + pre##_dblk(&ctx->ctx, t, u); \ \ /* --- Second stage --- * \ * \ @@ -358,14 +332,10 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ * three. \ */ \ \ - BLKC_STORE(PRE, b, bk); \ + BLKC_STORE(PRE, b, u); \ s += PRE##_BLKSZ; \ d += PRE##_BLKSZ; \ - for (i = 0; i < sz; i++) { \ - register octet x = s[i]; \ - d[i] = b[i] ^ x; \ - b[i] = x; \ - } \ + for (i = 0; i < sz; i++) { y = s[i]; d[i] = b[i] ^ y; b[i] = y; } \ \ /* --- Third stage --- * \ * \ @@ -373,10 +343,10 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ * recover the complete plaintext block. \ */ \ \ - BLKC_LOAD(PRE, bk, b); \ - pre##_dblk(&ctx->ctx, bk, bk); \ - BLKC_XSTORE(PRE, d - PRE##_BLKSZ, bk, ctx->iv); \ - BLKC_MOVE(PRE, ctx->iv, niv); \ + BLKC_LOAD(PRE, u, b); \ + pre##_dblk(&ctx->ctx, u, u); \ + BLKC_XSTORE(PRE, d - PRE##_BLKSZ, u, ctx->a); \ + BLKC_MOVE(PRE, ctx->a, t); \ } \ \ /* --- Done --- */ \ @@ -402,29 +372,16 @@ static gcipher *ginit(const void *k, size_t sz) \ } \ \ static void gencrypt(gcipher *c, const void *s, void *t, size_t sz) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_cbcencrypt(&g->k, s, t, sz); \ -} \ + { gctx *g = (gctx *)c; pre##_cbcencrypt(&g->k, s, t, sz); } \ \ static void gdecrypt(gcipher *c, const void *s, void *t, size_t sz) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_cbcdecrypt(&g->k, s, t, sz); \ -} \ + { gctx *g = (gctx *)c; pre##_cbcdecrypt(&g->k, s, t, sz); } \ \ static void gdestroy(gcipher *c) \ -{ \ - gctx *g = (gctx *)c; \ - BURN(*g); \ - S_DESTROY(g); \ -} \ + { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); } \ \ static void gsetiv(gcipher *c, const void *iv) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_cbcsetiv(&g->k, iv); \ -} \ + { gctx *g = (gctx *)c; pre##_cbcsetiv(&g->k, iv); } \ \ static const gcipher_ops gops = { \ &pre##_cbc, \ @@ -444,9 +401,7 @@ CBC_TESTX(PRE, pre, name, fname) #ifdef TEST_RIG -#include - -#include "daftstory.h" +#include "modes-test.h" /* --- @CBC_TEST@ --- * * @@ -457,85 +412,28 @@ CBC_TESTX(PRE, pre, name, fname) #define CBC_TESTX(PRE, pre, name, fname) \ \ -/* --- Initial plaintext for the test --- */ \ - \ -static const octet text[] = TEXT; \ +static pre##_ctx key; \ +static pre##_cbcctx ctx; \ \ -/* --- Key and IV to use --- */ \ +static void pre##_cbc_test_setup(const octet *k, size_t ksz) \ + { pre##_init(&key, k, ksz); pre##_cbcsetkey(&ctx, &key); } \ \ -static const octet key[] = KEY; \ -static const octet iv[] = IV; \ +static void pre##_cbc_test_reset(const octet *iv) \ + { pre##_cbcsetiv(&ctx, iv); } \ \ -/* --- Buffers for encryption and decryption output --- */ \ +static void pre##_cbc_test_enc(const octet *s, octet *d, size_t sz) \ + { pre##_cbcencrypt(&ctx, s, d, sz); } \ \ -static octet ct[sizeof(text)]; \ -static octet pt[sizeof(text)]; \ +static void pre##_cbc_test_dec(const octet *s, octet *d, size_t sz) \ + { pre##_cbcdecrypt(&ctx, s, d, sz); } \ \ -static void hexdump(const octet *p, size_t sz, size_t off) \ +int main(int argc, char *argv[]) \ { \ - const octet *q = p + sz; \ - for (sz = 0; p < q; p++, sz++) { \ - printf("%02x", *p); \ - if ((off + sz + 1) % PRE##_BLKSZ == 0) \ - putchar(':'); \ - } \ -} \ - \ -int main(void) \ -{ \ - size_t sz = 0, rest; \ - pre##_cbcctx ctx; \ - pre##_ctx k; \ - int status = 0; \ - int done = 0; \ - \ - size_t keysz = PRE##_KEYSZ ? \ - PRE##_KEYSZ : strlen((const char *)key); \ - \ - fputs(name "-cbc: ", stdout); \ - \ - pre##_init(&k, key, keysz); \ - pre##_cbcsetkey(&ctx, &k); \ - \ - while (sz <= sizeof(text)) { \ - rest = sizeof(text) - sz; \ - memcpy(ct, text, sizeof(text)); \ - pre##_cbcsetiv(&ctx, iv); \ - pre##_cbcencrypt(&ctx, ct, ct, sz); \ - pre##_cbcencrypt(&ctx, ct + sz, ct + sz, rest); \ - memcpy(pt, ct, sizeof(text)); \ - pre##_cbcsetiv(&ctx, iv); \ - pre##_cbcdecrypt(&ctx, pt, pt, sz); \ - pre##_cbcdecrypt(&ctx, pt + sz, pt + sz, rest); \ - if (memcmp(pt, text, sizeof(text)) == 0) { \ - done++; \ - if (sizeof(text) < 40 || done % 8 == 0) \ - fputc('.', stdout); \ - if (done % 480 == 0) \ - fputs("\n\t", stdout); \ - fflush(stdout); \ - } else { \ - printf("\nError (sz = %lu)\n", (unsigned long)sz); \ - status = 1; \ - printf("\tplaintext = "); hexdump(text, sz, 0); \ - printf(", "); hexdump(text + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\tciphertext = "); hexdump(ct, sz, 0); \ - printf(", "); hexdump(ct + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\trecovered text = "); hexdump(pt, sz, 0); \ - printf(", "); hexdump(pt + sz, rest, sz); \ - fputc('\n', stdout); \ - fputc('\n', stdout); \ - } \ - if (sz < 63) \ - sz++; \ - else \ - sz += 9; \ - } \ - \ - fputs(status ? " failed\n" : " ok\n", stdout); \ - return (status); \ + return test_encmode(fname "-cbc", PRE##_KEYSZ, PRE##_BLKSZ, \ + 1, TEMF_REFALIGN, \ + pre##_cbc_test_setup, pre##_cbc_test_reset, \ + pre##_cbc_test_enc, pre##_cbc_test_dec, \ + argc, argv); \ } #else diff --git a/symm/cbc.h b/symm/cbc.h index 5f1f22aa..7b21eea0 100644 --- a/symm/cbc.h +++ b/symm/cbc.h @@ -57,7 +57,7 @@ \ typedef struct pre##_cbcctx { \ pre##_ctx ctx; /* Underlying cipher context */ \ - uint32 iv[PRE##_BLKSZ / 4]; /* Previous ciphertext or IV */ \ + uint32 a[PRE##_BLKSZ/4]; /* Previous ciphertext or IV */ \ } pre##_cbcctx; \ \ /* --- @pre_cbcgetiv@ --- * \ diff --git a/symm/ccm-def.h b/symm/ccm-def.h new file mode 100644 index 00000000..2d864fa6 --- /dev/null +++ b/symm/ccm-def.h @@ -0,0 +1,902 @@ +/* -*-c-*- + * + * The CCM authenticated-encryption mode + * + * (c) 2017 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef CATACOMB_CCM_DEF_H +#define CATACOMB_CCM_DEF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +#ifndef CATACOMB_ARENA_H +# include "arena.h" +#endif + +#ifndef CATACOMB_BLKC_H +# include "blkc.h" +#endif + +#ifndef CATACOMB_CT_H +# include "ct.h" +#endif + +#ifndef CATACOMB_KEYSZ_H +# include "keysz.h" +#endif + +#ifndef CATACOMB_PARANOIA_H +# include "paranoia.h" +#endif + +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + +/*----- Common machinery --------------------------------------------------*/ + +/* --- @ccm_check@ --- * + * + * Arguments: @const ccm_params *p@ = pointer to parameters + * + * Returns: True (nonzero) if the parameters are OK; false (zero) if + * there's a problem. + * + * Use: Verify that the CCM parameters are acceptable. + */ + +extern int ccm_check(const ccm_params */*p*/); + +/* --- @ccm_fmthdr@ --- * + * + * Arguments: @const ccm_params *p@ = pointer to parameters + * @octet *b@ = block-size buffer to write header + * @const void *n@ = pointer to nonce + * + * Returns: --- + * + * Use: Format a MAC header block. + */ + +extern void ccm_fmthdr(const ccm_params */*p*/, + octet */*b*/, const void */*n*/); + +/* --- @ccm_fmtctr@ --- * + * + * Arguments: @const ccm_params *p@ = pointer to parameters + * @octet *b@ = block-size buffer to write header + * @const void *n@ = pointer to nonce + * + * Returns: --- + * + * Use: Format an initial counter block. + */ + +extern void ccm_fmtctr(const ccm_params */*p*/, + octet */*b*/, const void */*n*/); + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @CCM_DEF@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates an implementation for the CCM authenticated- + * encryption mode. + */ + +#define CCM_DEF(PRE, pre) CCM_DEFX(PRE, pre, #pre, #pre) + +#define CCM_DEFX(PRE, pre, name, fname) \ + \ +const octet pre##_ccmnoncesz[] = \ + { KSZ_RANGE, PRE##_BLKSZ/2 - (PRE##_BLKSZ <= 16 ? 1 : 2), \ + CCM_NSZMIN(PRE), CCM_NSZMAX(PRE), 1 }; \ +const octet pre##_ccmtagsz[] = \ + { KSZ_RANGE, CCM_TSZMAX(PRE), \ + CCM_TSZMIN(PRE), CCM_TSZMAX(PRE), PRE##_BLKSZ == 16 ? 2 : 1 }; \ + \ +static const rsvr_policy pre##_ccmpolicy = \ + { RSVRF_FULL, PRE##_BLKSZ, PRE##_BLKSZ }; \ + \ +/* --- @pre_ccminthash@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to context block \ + * @const void *p@ = pointer to material to hash \ + * @size_t sz@ = size of the input buffer \ + * \ + * Returns: --- \ + * \ + * Use: Internal operation for feeding stuff into the CBC-MAC \ + * context. \ + */ \ + \ +static void pre##_ccminthash(pre##_ccmctx *ctx, \ + const void *p, size_t sz) \ +{ \ + rsvr_state st; \ + const octet *q; \ + \ + rsvr_setup(&st, &pre##_ccmpolicy, ctx->b, &ctx->off, p, sz); \ + RSVR_DO(&st) while ((q = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \ + BLKC_XLOAD(PRE, ctx->a, q); \ + pre##_eblk(&ctx->k, ctx->a, ctx->a); \ + } \ +} \ + \ +/* --- @pre_ccminit@ --- * \ + * \ + * Arguments: @pre_ccmctx *aad@ = pointer to CCM context \ + * @const pre_ctx *k@ = pointer to key material \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of the nonce \ + * @size_t hsz@ = size of the AAD \ + * @size_t msz@ = size of the message/ciphertext \ + * @size_t tsz@ = size of the tag to produce \ + * \ + * Returns: Zero on success; nonzero if the parameters are invalid. \ + * \ + * Use: Initialize an CCM operation context with a given key. \ + * \ + * The original key needn't be kept around any more. \ + */ \ + \ +int pre##_ccminit(pre##_ccmctx *ctx, const pre##_ctx *k, \ + const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ + { ctx->k = *k; return (pre##_ccmreinit(ctx, n, nsz, hsz, msz, tsz)); } \ + \ +/* --- @pre_ccmreinit@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to CCM context \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * @size_t hsz@ = size of the AAD \ + * @size_t msz@ = size of the message/ciphertext \ + * @size_t tsz@ = size of the tag to produce \ + * \ + * Returns: Zero on success; nonzero if the parameters are invalid. \ + * \ + * Use: Reinitialize an CCM operation context, changing the \ + * nonce. \ + */ \ + \ +int pre##_ccmreinit(pre##_ccmctx *ctx, const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + kludge64 t; \ + octet b[12]; \ + size_t sz; \ + \ + /* Set up the parameters and check that they make sense. */ \ + ctx->p.hsz = hsz; ctx->p.msz = msz; \ + ctx->p.bsz = PRE##_BLKSZ; ctx->p.nsz = nsz; ctx->p.tsz = tsz; \ + if (!ccm_check(&ctx->p)) return (-1); \ + \ + /* Prepare the counter and the final MAC mask. The initial counter \ + * is used to make the MAC mask, so generate that, keeping it for \ + * later. \ + */ \ + ccm_fmtctr(&ctx->p, ctx->b, n); \ + BLKC_LOAD(PRE, ctx->c, ctx->b); \ + pre##_eblk(&ctx->k, ctx->c, ctx->s0); \ + \ + /* Prepare the MAC header and leave it in the buffer. */ \ + ccm_fmthdr(&ctx->p, ctx->b, n); \ + BLKC_ZERO(PRE, ctx->a); \ + \ + /* Initialize our state. The buffer is currently full (with the \ + * MAC header), and we're always awaiting AAD, though we've not yet \ + * seen any. (Even if we're not expecting AAD, this will trigger \ + * appropriate initialization when encryption or decryption begins.) \ + */ \ + ctx->off = PRE##_BLKSZ; ctx->i = 0; \ + ctx->st = CCMST_AAD; \ + \ + /* If there's AAD to come, then do the AAD framing. This aligns \ + * badly with the blocking, so feed the framing in the hard way. \ + */ \ + if (hsz) { \ + if (hsz < 0xfffe) \ + { STORE16(b, hsz); sz = 2; } \ + else if (hsz <= MASK32) \ + { b[0] = 0xff; b[1] = 0xfe; STORE32(b + 2, hsz); sz = 6; } \ + else { \ + b[0] = b[1] = 0xff; \ + ASSIGN64(t, hsz); STORE64_(b + 2, t); \ + sz = 10; \ + } \ + pre##_ccminthash(ctx, b, sz); \ + } \ + \ + /* All done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ccmaadhash@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to AAD context \ + * @const void *p@ = pointer to AAD material \ + * @size_t sz@ = length of AAD material \ + * \ + * Returns: --- \ + * \ + * Use: Feeds AAD into the context. This must be done before \ + * any of the message/ciphertext is processed because CCM \ + * is really annoying like that. \ + */ \ + \ +void pre##_ccmaadhash(pre##_ccmctx *ctx, const void *p, size_t sz) \ +{ \ + assert(ctx->st == CCMST_AAD); \ + assert(sz <= ctx->p.hsz - ctx->i); \ + ctx->i += sz; \ + pre##_ccminthash(ctx, p, sz); \ +} \ + \ +/* --- @pre_ccmencdecsetup@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to context block \ + * @size_t sz@ = size of message block \ + * \ + * Returns: --- \ + * \ + * Use: Prepares for an encrypt or decryption operation, \ + * transitioning from the AAD state and updating the \ + * message size. \ + */ \ + \ +static void pre##_ccmencdecsetup(pre##_ccmctx *ctx, size_t sz) \ +{ \ + if (ctx->st != CCMST_MSG) { \ + /* Make sure we're currently in the AAD state and we've seen all of \ + * the AAD we expected. \ + */ \ + assert(ctx->st == CCMST_AAD); \ + assert(ctx->i == ctx->p.hsz); \ + \ + /* Pad the final AAD block out until we hit a block boundary. Note \ + * that we don't cycle the block cipher here: instead, leave the \ + * buffer full so that we do that next time. \ + */ \ + memset(ctx->b + ctx->off, 0, PRE##_BLKSZ - ctx->off); \ + ctx->off = PRE##_BLKSZ; \ + \ + /* Now we're ready to process the message text. */ \ + ctx->st = CCMST_MSG; ctx->i = 0; \ + } \ + \ + /* Update the size. */ \ + assert(sz <= ctx->p.msz - ctx->i); \ + ctx->i += sz; \ +} \ + \ +/* --- @pre_ccmencrypt@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to CCM operation context \ + * @const void *src@ = pointer to plaintext message chunk \ + * @size_t sz@ = size of the plaintext \ + * @buf *dst@ = a buffer to write the ciphertext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Encrypts a chunk of a plaintext message, writing a \ + * chunk of ciphertext to the output buffer and updating \ + * the operation state. \ + * \ + * For CCM, we always write a ciphertext chunk the same \ + * size as the plaintext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +int pre##_ccmencrypt(pre##_ccmctx *ctx, \ + const void *src, size_t sz, buf *dst) \ +{ \ + rsvr_plan plan; \ + uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ]; \ + const octet *p = src; \ + octet *q, *r, y; \ + \ + /* Allocate space for the ciphertext. */ \ + if (sz) { q = buf_get(dst, sz); if (!q) return (-1); } \ + else q = 0; \ + \ + /* Set stuff up. */ \ + pre##_ccmencdecsetup(ctx, sz); \ + \ + /* Determine the buffering plan. Our buffer is going to do double- \ + * duty here. The end portion is going to contain mask from the \ + * encrypted counter which we mix into the plaintext to encrypt it; \ + * the start portion, which originally mask bytes we've already used, \ + * will hold the input plaintext, which will eventually be \ + * collected into the CBC-MAC state. \ + */ \ + rsvr_mkplan(&plan, &pre##_ccmpolicy, ctx->off, sz); \ + \ + /* Initial portion, fulfilled from the buffer. If the buffer is \ + * empty, then that means that we haven't yet encrypted the current \ + * counter, so we should do that and advance it. \ + */ \ + if (plan.head) { \ + if (!ctx->off) { \ + BLKC_BSTEP(PRE, ctx->c); pre##_eblk(&ctx->k, ctx->c, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + } \ + r = ctx->b + ctx->off; ctx->off += plan.head; \ + while (plan.head--) { y = *p++; *q++ = y ^ *r; *r++ = y; } \ + } \ + \ + /* If we've filled up the buffer then we need to cycle the MAC and \ + * reset the offset. \ + */ \ + if (plan.from_rsvr) { \ + BLKC_XLOAD(PRE, ctx->a, ctx->b); \ + pre##_eblk(&ctx->k, ctx->a, ctx->a); \ + ctx->off = 0; \ + } \ + \ + /* Now to process the main body of the input. */ \ + while (plan.from_input) { \ + BLKC_BSTEP(PRE, ctx->c); pre##_eblk(&ctx->k, ctx->c, t); \ + BLKC_LOAD(PRE, u, p); p += PRE##_BLKSZ; \ + BLKC_XSTORE(PRE, q, t, u); q += PRE##_BLKSZ; \ + BLKC_XMOVE(PRE, ctx->a, u); pre##_eblk(&ctx->k, ctx->a, ctx->a); \ + plan.from_input -= PRE##_BLKSZ; \ + } \ + \ + /* Finally, deal with any final portion. If there is one, we know \ + * that the buffer is empty: we must have filled it above, or this \ + * would all count as `initial' data. \ + */ \ + if (plan.tail) { \ + BLKC_BSTEP(PRE, ctx->c); pre##_eblk(&ctx->k, ctx->c, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + r = ctx->b; ctx->off = plan.tail; \ + while (plan.tail--) { y = *p++; *q++ = y ^ *r; *r++ = y; } \ + } \ + \ + /* Done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ccmdecrypt@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to CCM operation context \ + * @const void *src@ = pointer to ciphertext message chunk \ + * @size_t sz@ = size of the ciphertext \ + * @buf *dst@ = a buffer to write the plaintext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Decrypts a chunk of a ciphertext message, writing a \ + * chunk of plaintext to the output buffer and updating \ + * the operation state. \ + * \ + * For CCM, we always write a plaintext chunk the same \ + * size as the ciphertext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +int pre##_ccmdecrypt(pre##_ccmctx *ctx, \ + const void *src, size_t sz, buf *dst) \ +{ \ + rsvr_plan plan; \ + uint32 t[PRE##_BLKSZ/4]; \ + const octet *p = src; \ + octet *q, *r, y; \ + \ + /* Allocate space for the plaintext. */ \ + if (sz) { q = buf_get(dst, sz); if (!q) return (-1); } \ + else q = 0; \ + \ + /* Set stuff up. */ \ + pre##_ccmencdecsetup(ctx, sz); \ + \ + /* Determine the buffering plan. Our buffer is going to do double- \ + * duty here. The end portion is going to contain mask from the \ + * encrypted counter which we mix into the plaintext to encrypt it; \ + * the start portion, which originally mask bytes we've already used, \ + * will hold the recovered plaintext, which will eventually be \ + * collected into the CBC-MAC state. \ + */ \ + rsvr_mkplan(&plan, &pre##_ccmpolicy, ctx->off, sz); \ + \ + /* Initial portion, fulfilled from the buffer. If the buffer is \ + * empty, then that means that we haven't yet encrypted the current \ + * counter, so we should do that and advance it. \ + */ \ + if (plan.head) { \ + if (!ctx->off) { \ + BLKC_BSTEP(PRE, ctx->c); pre##_eblk(&ctx->k, ctx->c, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + } \ + r = ctx->b + ctx->off; ctx->off += plan.head; \ + while (plan.head--) { y = *p++ ^ *r; *q++ = *r++ = y; } \ + } \ + \ + /* If we've filled up the buffer then we need to cycle the MAC and \ + * reset the offset. \ + */ \ + if (plan.from_rsvr) { \ + BLKC_XLOAD(PRE, ctx->a, ctx->b); \ + pre##_eblk(&ctx->k, ctx->a, ctx->a); \ + ctx->off = 0; \ + } \ + \ + /* Now to process the main body of the input. */ \ + while (plan.from_input) { \ + BLKC_BSTEP(PRE, ctx->c); pre##_eblk(&ctx->k, ctx->c, t); \ + BLKC_XLOAD(PRE, t, p); p += PRE##_BLKSZ; \ + BLKC_STORE(PRE, q, t); q += PRE##_BLKSZ; \ + BLKC_XMOVE(PRE, ctx->a, t); pre##_eblk(&ctx->k, ctx->a, ctx->a); \ + plan.from_input -= PRE##_BLKSZ; \ + } \ + \ + /* Finally, deal with any final portion. If there is one, we know \ + * that the buffer is empty: we must have filled it above, or this \ + * would all count as `initial' data. \ + */ \ + if (plan.tail) { \ + BLKC_BSTEP(PRE, ctx->c); pre##_eblk(&ctx->k, ctx->c, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + r = ctx->b; ctx->off = plan.tail; \ + while (plan.tail--) { y = *p++ ^ *r; *q++ = *r++ = y; } \ + } \ + \ + /* Done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ccmtag@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to an CCM context \ + * @octet *t@ = where to write a (full-length) tag \ + * @size_t tsz@ = size of the tag (to check) \ + * \ + * Returns: --- \ + * \ + * Use: Finishes an CCM operation, by calculating the tag. \ + */ \ + \ +static void pre##_ccmtag(pre##_ccmctx *ctx, octet *t, size_t tsz) \ +{ \ + /* Make sure we're in good shape. It's just about possible that \ + * we're still in the AAD state, but there was no actual message, so \ + * handle this situation. \ + */ \ + switch (ctx->st) { \ + case CCMST_AAD: \ + assert(ctx->i == ctx->p.hsz); \ + assert(!ctx->p.msz); \ + break; \ + case CCMST_MSG: \ + /* hsz already checked in `pre_ccmencdecsetup'. */ \ + assert(ctx->i == ctx->p.msz); \ + break; \ + default: abort(); \ + } \ + assert(tsz == ctx->p.tsz); \ + \ + /* Pad the final plaintext block out and cycle the block cipher one \ + * last time. \ + */ \ + memset(ctx->b + ctx->off, 0, PRE##_BLKSZ - ctx->off); \ + BLKC_XLOAD(PRE, ctx->a, ctx->b); \ + pre##_eblk(&ctx->k, ctx->a, ctx->a); \ + \ + /* Mask the CBC-MAC tag (which prevents the standard extension \ + * attack) and store the result. \ + */ \ + BLKC_XSTORE(PRE, t, ctx->a, ctx->s0); \ +} \ + \ +/* --- @pre_ccmencryptdone@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to an CCM context \ + * @buf *dst@ = buffer for remaining ciphertext \ + * @void *tag@ = where to write the tag \ + * @size_t tsz@ = length of tag to store \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Completes an CCM encryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. CCM doesn't buffer ciphertext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +int pre##_ccmencryptdone(pre##_ccmctx *ctx, buf *dst, \ + void *tag, size_t tsz) \ +{ \ + octet t[PRE##_BLKSZ]; \ + \ + /* Some initial checks. */ \ + if (!BOK(dst)) return (-1); \ + \ + /* Calculate and return the tag. */ \ + pre##_ccmtag(ctx, t, tsz); \ + memcpy(tag, t, tsz); \ + \ + /* Done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ccmdecryptdone@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to an CCM context \ + * @buf *dst@ = buffer for remaining plaintext \ + * @const void *tag@ = tag to verify \ + * @size_t tsz@ = length of tag \ + * \ + * Returns: @+1@ for complete success; @0@ if tag verification \ + * failed; @-1@ for other kinds of errors. \ + * \ + * Use: Completes an CCM decryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. CCM doesn't buffer plaintext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +int pre##_ccmdecryptdone(pre##_ccmctx *ctx, buf *dst, \ + const void *tag, size_t tsz) \ +{ \ + octet t[PRE##_BLKSZ]; \ + \ + /* Some initial checks. */ \ + if (!BOK(dst)) return (-1); \ + \ + /* Calculate and check the tag. */ \ + pre##_ccmtag(ctx, t, tsz); \ + if (!ct_memeq(tag, t, tsz)) return (0); \ + else return (+1); \ +} \ + \ +/* --- Generic AEAD interface --- */ \ + \ +typedef struct gctx { \ + gaead_aad a; \ + pre##_ccmctx ctx; \ +} gctx; \ + \ +static void gahash(gaead_aad *a, const void *h, size_t hsz) \ + { gctx *ctx = (gctx *)a; pre##_ccmaadhash(&ctx->ctx, h, hsz); } \ + \ +static void gadestroy(gaead_aad *a) { ; } \ + \ +static const gaead_aadops gaops = \ + { &pre##_ccm, 0, gahash, gadestroy }; \ + \ +typedef struct gectx { \ + gaead_enc e; \ + gctx g; \ +} gectx; \ + \ +static gaead_aad *geaad(gaead_enc *e) \ + { gectx *enc = (gectx *)e; return (&enc->g.a); } \ + \ +static int gereinit(gaead_enc *e, const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gectx *enc = (gectx *)e; \ + return (pre##_ccmreinit(&enc->g.ctx, n, nsz, hsz, msz, tsz)); \ +} \ + \ +static int geenc(gaead_enc *e, const void *m, size_t msz, buf *b) \ +{ \ + gectx *enc = (gectx *)e; \ + return (pre##_ccmencrypt(&enc->g.ctx, m, msz, b)); \ +} \ + \ +static int gedone(gaead_enc *e, const gaead_aad *a, \ + buf *b, void *t, size_t tsz) \ +{ \ + gectx *enc = (gectx *)e; \ + assert((!a && !enc->g.ctx.p.hsz) || a == &enc->g.a); \ + return (pre##_ccmencryptdone(&enc->g.ctx, b, t, tsz)); \ +} \ + \ +static void gedestroy(gaead_enc *e) \ + { gectx *enc = (gectx *)e; BURN(*enc); S_DESTROY(enc); } \ + \ +static const gaead_encops geops = \ + { &pre##_ccm, geaad, gereinit, geenc, gedone, gedestroy }; \ + \ +typedef struct gdctx { \ + gaead_dec d; \ + gctx g; \ +} gdctx; \ + \ +static gaead_aad *gdaad(gaead_dec *d) \ + { gdctx *dec = (gdctx *)d; return (&dec->g.a); } \ + \ +static int gdreinit(gaead_dec *d, const void *n, size_t nsz, \ + size_t hsz, size_t csz, size_t tsz) \ +{ \ + gdctx *dec = (gdctx *)d; \ + return (pre##_ccmreinit(&dec->g.ctx, n, nsz, hsz, csz, tsz)); \ +} \ + \ +static int gddec(gaead_dec *d, const void *c, size_t csz, buf *b) \ +{ \ + gdctx *dec = (gdctx *)d; \ + return (pre##_ccmdecrypt(&dec->g.ctx, c, csz, b)); \ +} \ + \ +static int gddone(gaead_dec *d, const gaead_aad *a, \ + buf *b, const void *t, size_t tsz) \ +{ \ + gdctx *dec = (gdctx *)d; \ + assert((!a && !dec->g.ctx.p.hsz) || a == &dec->g.a); \ + return (pre##_ccmdecryptdone(&dec->g.ctx, b, t, tsz)); \ +} \ + \ +static void gddestroy(gaead_dec *d) \ + { gdctx *dec = (gdctx *)d; BURN(*dec); S_DESTROY(dec); } \ + \ +static const gaead_decops gdops = \ + { &pre##_ccm, gdaad, gdreinit, gddec, gddone, gddestroy }; \ + \ +typedef struct gkctx { \ + gaead_key k; \ + pre##_ctx key; \ +} gkctx; \ + \ +static gaead_enc *gkenc(const gaead_key *k, const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gkctx *key = (gkctx *)k; \ + gectx *enc = S_CREATE(gectx); \ + \ + enc->e.ops = &geops; enc->g.a.ops = &gaops; \ + if (pre##_ccminit(&enc->g.ctx, &key->key, n, nsz, hsz, msz, tsz)) \ + { gedestroy(&enc->e); return (0); } \ + return (&enc->e); \ +} \ + \ +static gaead_dec *gkdec(const gaead_key *k, const void *n, size_t nsz, \ + size_t hsz, size_t csz, size_t tsz) \ +{ \ + gkctx *key = (gkctx *)k; \ + gdctx *dec = S_CREATE(gdctx); \ + \ + dec->d.ops = &gdops; dec->g.a.ops = &gaops; \ + if (pre##_ccminit(&dec->g.ctx, &key->key, n, nsz, hsz, csz, tsz)) \ + { gddestroy(&dec->d); return (0); } \ + return (&dec->d); \ +} \ + \ +static void gkdestroy(gaead_key *k) \ + { gkctx *key = (gkctx *)k; BURN(*key); S_DESTROY(key); } \ + \ +static const gaead_keyops gkops = \ + { &pre##_ccm, 0, gkenc, gkdec, gkdestroy }; \ + \ +static gaead_key *gckey(const void *k, size_t ksz) \ +{ \ + gkctx *key = S_CREATE(gkctx); \ + key->k.ops = &gkops; \ + pre##_init(&key->key, k, ksz); \ + return (&key->k); \ +} \ + \ +const gcaead pre##_ccm = { \ + name "-ccm", \ + pre##_keysz, pre##_ccmnoncesz, pre##_ccmtagsz, \ + PRE##_BLKSZ, 0, 0, \ + AEADF_PCHSZ | AEADF_PCMSZ | AEADF_PCTSZ | \ + AEADF_AADNDEP | AEADF_AADFIRST, \ + gckey \ +}; \ + \ +CCM_TESTX(PRE, pre, name, fname) + +/*----- Test rig ----------------------------------------------------------*/ + +#define CCM_TEST(PRE, pre) CCM_TESTX(PRE, pre, #pre, #pre) + +/* --- @CCM_TEST@ --- * + * + * Arguments: @PRE, pre@ = prefixes for the underlying block cipher + * + * Use: Standard test rig for CCM functions. + */ + +#ifdef TEST_RIG + +#include + +#include +#include +#include + +#define CCM_TESTX(PRE, pre, name, fname) \ + \ +static int ccmverify(dstr *v) \ +{ \ + pre##_ctx key; \ + pre##_ccmctx ctx; \ + int ok = 1, win; \ + int i; \ + octet *p; \ + int szs[] = { 1, 7, 192, -1, 0 }, *ip; \ + size_t hsz, msz; \ + dstr d = DSTR_INIT, t = DSTR_INIT; \ + buf b; \ + \ + dstr_ensure(&d, v[4].len > v[3].len ? v[4].len : v[3].len); \ + dstr_ensure(&t, v[5].len); t.len = v[5].len; \ + \ + pre##_init(&key, v[0].buf, v[0].len); \ + \ + for (ip = szs; *ip; ip++) { \ + \ + pre##_ccminit(&ctx, &key, (octet *)v[1].buf, v[1].len, \ + v[2].len, v[3].len, v[5].len); \ + \ + i = *ip; \ + hsz = v[2].len; \ + if (i == -1) i = hsz; \ + if (i > hsz) continue; \ + p = (octet *)v[2].buf; \ + while (hsz) { \ + if (i > hsz) i = hsz; \ + pre##_ccmaadhash(&ctx, p, i); \ + p += i; hsz -= i; \ + } \ + \ + buf_init(&b, d.buf, d.sz); \ + i = *ip; \ + msz = v[3].len; \ + if (i == -1) i = msz; \ + if (i > msz) continue; \ + p = (octet *)v[3].buf; \ + while (msz) { \ + if (i > msz) i = msz; \ + if (pre##_ccmencrypt(&ctx, p, i, &b)) { \ + puts("!! ccmencrypt reports failure"); \ + goto fail_enc; \ + } \ + p += i; msz -= i; \ + } \ + \ + if (pre##_ccmencryptdone(&ctx, &b, (octet *)t.buf, t.len)) { \ + puts("!! ccmencryptdone reports failure"); \ + goto fail_enc; \ + } \ + d.len = BLEN(&b); \ + \ + if (d.len != v[4].len || \ + memcmp(d.buf, v[4].buf, v[4].len) != 0 || \ + memcmp(t.buf, v[5].buf, v[5].len) != 0) { \ + fail_enc: \ + printf("\nfail encrypt:\n\tstep = %i", *ip); \ + fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \ + fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \ + fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \ + fputs("\n\tmessage = ", stdout); type_hex.dump(&v[3], stdout); \ + fputs("\n\texp ct = ", stdout); type_hex.dump(&v[4], stdout); \ + fputs("\n\tcalc ct = ", stdout); type_hex.dump(&d, stdout); \ + fputs("\n\texp tag = ", stdout); type_hex.dump(&v[5], stdout); \ + fputs("\n\tcalc tag = ", stdout); type_hex.dump(&t, stdout); \ + putchar('\n'); \ + ok = 0; \ + } \ + \ + pre##_ccminit(&ctx, &key, (octet *)v[1].buf, v[1].len, \ + v[2].len, v[4].len, v[5].len); \ + \ + i = *ip; \ + hsz = v[2].len; \ + if (i == -1) i = hsz; \ + if (i > hsz) continue; \ + p = (octet *)v[2].buf; \ + while (hsz) { \ + if (i > hsz) i = hsz; \ + pre##_ccmaadhash(&ctx, p, i); \ + p += i; hsz -= i; \ + } \ + \ + buf_init(&b, d.buf, d.sz); \ + i = *ip; \ + msz = v[4].len; \ + if (i == -1) i = msz; \ + if (i > msz) continue; \ + p = (octet *)v[4].buf; \ + while (msz) { \ + if (i > msz) i = msz; \ + if (pre##_ccmdecrypt(&ctx, p, i, &b)) { \ + puts("!! ccmdecrypt reports failure"); \ + win = 0; goto fail_dec; \ + } \ + p += i; msz -= i; \ + } \ + \ + win = pre##_ccmdecryptdone(&ctx, &b, (octet *)v[5].buf, v[5].len); \ + if (win < 0) { \ + puts("!! ccmdecryptdone reports failure"); \ + goto fail_dec; \ + } \ + d.len = BLEN(&b); \ + \ + if (d.len != v[3].len || !win || \ + memcmp(d.buf, v[3].buf, v[3].len) != 0) { \ + fail_dec: \ + printf("\nfail decrypt:\n\tstep = %i", *ip); \ + fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \ + fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \ + fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \ + fputs("\n\tciphertext = ", stdout); type_hex.dump(&v[4], stdout); \ + fputs("\n\texp pt = ", stdout); type_hex.dump(&v[3], stdout); \ + fputs("\n\tcalc pt = ", stdout); type_hex.dump(&d, stdout); \ + fputs("\n\ttag = ", stdout); type_hex.dump(&v[5], stdout); \ + printf("\n\tverify %s", win ? "ok" : "FAILED"); \ + putchar('\n'); \ + ok = 0; \ + } \ + } \ + \ + dstr_destroy(&d); dstr_destroy(&t); \ + return (ok); \ +} \ + \ +static test_chunk aeaddefs[] = { \ + { name "-ccm", ccmverify, \ + { &type_hex, &type_hex, &type_hex, &type_hex, \ + &type_hex, &type_hex, 0 } }, \ + { 0, 0, { 0 } } \ +}; \ + \ +int main(int argc, char *argv[]) \ +{ \ + ego(argv[0]); \ + test_run(argc, argv, aeaddefs, SRCDIR"/t/" fname); \ + return (0); \ +} + +#else +# define CCM_TESTX(PRE, pre, name, fname) +#endif + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/ccm.c b/symm/ccm.c new file mode 100644 index 00000000..d65e0490 --- /dev/null +++ b/symm/ccm.c @@ -0,0 +1,201 @@ +/* -*-c-*- + * + * CCM common code + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "ccm.h" +#include "ccm-def.h" + +/*----- MAC header and counter formatting ---------------------------------* + * + * CCM's most endearing feature is its complex formatting of the MAC + * initialization vector and counter blocks. This is only specified for + * 128-bit blocks, so I've made up formats for 64-, 192-, and 256-bit blocks. + * For completeness and ease of comparison, all of the encodings are defined + * here. Encoding of the rest of the MAC input data is common. + * + * The notation is taken from the definition of CCM in NIST SP800-38C. + * + * * [x]_w = encoding of x, as w bits + * * P = plaintext/ciphertext + * * p = length of P in octets + * * Q = [p]_{8q} = encoding of p + * * q = length of Q in octets + * * N = nonce + * * H = B_0 = MAC header block + * * C_i = the i-th counter block + * * t = length of tag in octets + * + * 128-bit blocks (SP800-38C, appendix A): + * + * Let F be an octet: + * + * Bits 7 6 6:3 3:0 + * Meaning 0 AAD? [t/2 - 1]_3 [q - 1]_3 + * + * Then H = F || N || Q and C_i = 0^5 || [q - 1]_3 || N || [i]_{8q}. + * + * 64-bit blocks (new): + * + * Let F be an octet: + * + * Bits 7 6 6:3 3:0 + * Meaning 0 AAD? [t - 1]_3 [q - 1]_3 + * + * Then H = F || N || Q and C_i = 0^5 || [q - 1]_3 || N || [i]_{8q}. + * + * (i.e., almost exactly the same, except that the tag no longer needs to be + * an even number of octets). + * + * n-bit blocks, for n > 128 + * + * Let F be a 16-bit flags word: + * + * Bits 15 15:8 7 7:0 + * Meaning 0 [t]_7 AAD? [q]_7 + * + * Then H = F || N || Q and C_i = 0^9 || [q - 1]_7 || N || [i]_{8q}. + */ + +/* --- @ccm_paramsok@ --- * + * + * Arguments: @const ccm_params *p@ = pointer to parameters + * + * Returns: True (nonzero) if the parameters are OK; false (zero) if + * there's a problem. + * + * Use: Verify that the CCM parameters are acceptable. + */ + +int ccm_check(const ccm_params *p) +{ + unsigned fsz = p->bsz <= 16 ? 1 : 2, q = p->bsz - p->nsz - fsz, i; + size_t msz; + + /* Check that the block size hasn't been bungled. */ + if (p->bsz < 16 && p->bsz != 8) return (0); + + /* The length-of-the-length must be representable, and its encoding must + * not be zero, since this is `reserved'. The small-block encoding stores + * %$q - 1$%, so we must have %$q \ge 2$%; the large-block encoding stores + * %$q$% directly, so only %$q = 0$% is forbidden. + */ + if (p->nsz > p->bsz - fsz - (p->bsz <= 16 ? 2 : 1)) return (0); + if (q > (p->bsz <= 16 ? 8 : 127)) return (0); + + /* Verify that the message length will fit in the space allotted. */ + for (i = 1, msz = p->msz >> 8; msz; i++, msz >>= 8); + if (i > q) return (0); + + /* The tag can't be larger than the block size. Also, it must be + * representable, and its encoding must not be zero, because otherwise it'd + * be possible for a MAC header block to look like a counter block. The + * tag encoding is fiddly: for 64-bit blocks, we store %$t - 1$%, so we + * must have %$t \ge 2$%; for 128-bit blocks, we store %$t/2 - 2$%, so + * we must have %$t \ge 4$% with %$t$% even; otherwise, we store %$t$% + * directly, so the only requirement is that %$t \ge 1$%. + */ + if (p->tsz > p->bsz) return (0); + if (p->tsz < (p->bsz == 8 ? 2 : p->bsz == 16 ? 4 : 1)) return (0); + if (p->bsz == 16 && p->tsz%2 != 0) return (0); + + /* All looks good. */ + return (1); +} + +/* --- @ccm_fmthdr@ --- * + * + * Arguments: @const ccm_params *p@ = pointer to parameters + * @octet *b@ = block-size buffer to write header + * @const void *n@ = pointer to nonce + * + * Returns: --- + * + * Use: Format a MAC header block. + */ + +void ccm_fmthdr(const ccm_params *p, octet *b, const void *n) +{ + size_t fsz = p->bsz <= 16 ? 1 : 2, q = p->bsz - p->nsz - fsz; + unsigned f0 = 0, f1 = 0; + size_t i, t; + + /* Encode whether the AAD is empty. */ + if (!p->hsz) /* do nothing */; + else if (p->bsz <= 16) f0 |= 0x40; + else f1 |= 0x80; + + /* Encode the tag size. */ + switch (p->bsz) { + case 8: f0 |= (p->tsz - 1) << 3; break; + case 16: f0 |= (p->tsz - 2) << 2; break; + default: f0 |= p->tsz; break; + } + + /* Encode the length-of-the-length. (This is the most bletcherous part of + * CCM.) + */ + if (p->bsz <= 16) f0 |= q - 1; + else f1 |= q; + + /* Insert the flags and nonce. */ + b[0] = f0; memcpy(b + fsz, n, p->nsz); + if (p->bsz > 16) b[1] = f1; + + /* Write the message length. */ + for (i = 0, t = p->msz; i < q; i++, t >>= 8) b[p->bsz - i - 1] = U8(t); +} + +/* --- @ccm_fmtctr@ --- * + * + * Arguments: @const ccm_params *p@ = pointer to parameters + * @octet *b@ = block-size buffer to write header + * @const void *n@ = pointer to nonce + * + * Returns: --- + * + * Use: Format an initial counter block. + */ + +void ccm_fmtctr(const ccm_params *p, octet *b, const void *n) +{ + size_t fsz = p->bsz <= 16 ? 1 : 2, q = p->bsz - p->nsz - fsz; + unsigned f0 = 0, f1 = 0; + + /* Encode the message length length. (Did I complain about this?) */ + if (p->bsz <= 16) f0 |= q - 1; + else f1 |= q; + + /* Insert the flags and nonce. */ + b[0] = f0; memcpy(b + fsz, n, p->nsz); + if (p->bsz > 16) b[1] = f1; + + /* Zero out the initial counter. */ + memset(b + fsz + p->nsz, 0, q); +} + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/symm/ccm.h b/symm/ccm.h new file mode 100644 index 00000000..ebbcc422 --- /dev/null +++ b/symm/ccm.h @@ -0,0 +1,327 @@ +/* -*-c-*- + * + * The CCM authenticated-encryption mode + * + * (c) 2017 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Notes on CCM ------------------------------------------------------* + * + * The name is short for `Counter with CBC-MAC'. CCM was designed in 2002 by + * Russ Housley, Doug Whiting, and Niels Ferguson to be a patent-free + * alternative to Rogaway's OCB, and is specified by NIST in SP800-38C. It's + * a classic two-pass authenticated encryption scheme, so it needs two + * blockcipher applications per message block. + * + * Unfortunately, CCM is rather annoying in actual use. The internals + * involve quite a lot of fiddly framing, which I've had to generalize for + * block sizes other than 128 bits, but that's not exposed beyond the API. + * (This does mean that it's rather unlikely that Catacomb's CCM will + * interoperate with anyone else's when using a blockcipher with a block size + * other than 128 bits.) + * + * More problematically: + * + * * The mode requires that callers precommit to the header, message, and + * tag sizes before commencing processing. If you don't know these in + * advance then you can't use CCM. + * + * * The mode requires that callers present all of the header data before + * encrypting the message. + * + * * The header data processing is dependent on the nonce (and the message + * and tag lengths), so it's not possible to preprocess a constant prefix + * of the header. + * + * * There's an uncomfortable tradeoff between nonce length and message + * length because the counter input holds both in separate fields, with a + * variably-positioned split between them. + * + * The implementation is very picky and will abort if you get things wrong. + */ + +#ifndef CATACOMB_CCM_H +#define CATACOMB_CCM_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +#ifndef CATACOMB_GAEAD_H +# include "gaead.h" +#endif + +/*----- Common machinery -------------------------------------------------*/ + +typedef struct ccm_params { + unsigned long hsz, msz; /* AAD and message lengths */ + unsigned bsz, nsz, tsz; /* Block, nonce and tag length */ +} ccm_params; + +enum { CCMST_AAD, CCMST_MSG }; + +/* Minimum and maximum nonce lengths. + * + * Let the block size be %$N$% bytes, and let %$q$% be the length-of-the- + * length of the messaage. The nonce length is not encoded directly; rather, + * it's what's left after the flags bytes and message length fields have been + * allocated. + * + * The maximum is always %$N - 3$%. If %$N \le 16$%, then there is one byte + * used for flags, and at least two bytes for the message length/counter: + * (since %$q$% is encoded in a 3-bit field as %$q - 1$%, %$q = 0$% cannot be + * encoded and the encoding zero, for %$q = 1$%, is reserved. If %$N > 16$ + * then there are two flags bytes, but %$q$% is encoded directly, so only + * %$q = 0$% is reserved. + * + * The minimum is more complicated. If %$N \le 16$% then we must have %$q + * \le 8$%; with one flags byte, this leaves at least %$\max\{ 0, N - 9 \}$% + * bytes for the nonce. When %$N = 8$% this is zero, but when %$N = 16$% + * this is 7. When %$N > 16$%, there are two flags bits, but %$q \le 127$% + * (since %$q$%) is encoded directly: thus the nonce may be empty if + * %$16 < N \le 129$%, and otherwise must be at least %$N - 129$% bytes. + */ +#define CCM_NSZMIN(PRE) (PRE##_BLKSZ == 16 ? 7 : \ + PRE##_BLKSZ <= 129 ? 0 : \ + PRE##_BLKSZ - 129) +#define CCM_NSZMAX(PRE) (PRE##_BLKSZ - 3) + +/* Minimum and maximum tag lengths. + * + * This is even more exasperating. Again, let the block size be %$N$% bytes; + * let %$t$% be the tag length. + * + * When %$N = 16$%, the tag length is encoded as %$t/2 - 1$% in a three-bit + * field, and the encoding zero is reserved. (The security of the scheme + * depends on this reservation to disambiguate MAC header blocks from + * counters; I'd have used the remaining flag bit.) Anyway, this leaves + * %$1 \le t/2 - 1 \le 7$%, so we must have %$4 \le t \le 16$% with %$t$% + * even. + * + * When %$N = 8$%, the tag length is encoded in three bits as %$t - 1$%; + * again, the zero encoding is reserved. This leaves %$2 \le t \le 8$%. + * + * Finally, when %$N \ge 16$%, the tag length is encoded directly in a + * seven-bit field. The zero encoding is still reserved, so we have + * %$1 \le t \le \min \{ N, 127 \}$%. + */ +#define CCM_TSZMIN(PRE) (PRE##_BLKSZ == 8 ? 2 : \ + PRE##_BLKSZ == 16 ? 4 : \ + 1) +#define CCM_TSZMAX(PRE) (PRE##_BLKSZ <= 127 ? PRE##_BLKSZ : 127) + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @CCM_DECL@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates declarations for CCM authenticated-encryption mode. + */ + +#define CCM_DECL(PRE, pre) \ + \ +typedef struct pre##_ccmctx { \ + /* The buffer is split into two portions during encryption/ \ + * decryption. The first N octets hold a chunk of plaintext, which \ + * will be fed into the CBC-MAC calculation; the remaining BLKSZ - N \ + * octets hold E_K(C), which is the XOR mask to apply to the \ + * plaintext or ciphertext. \ + */ \ + pre##_ctx k; /* Underlying key */ \ + ccm_params p; /* CCM parameters */ \ + unsigned long i; /* Current position in bytes */ \ + unsigned st; /* Current state */ \ + uint32 c[PRE##_BLKSZ/4]; /* Current counter value */ \ + uint32 a[PRE##_BLKSZ/4]; /* CBC-MAC accumulator */ \ + uint32 s0[PRE##_BLKSZ/4]; /* Mask for MAC tag */ \ + octet b[PRE##_BLKSZ]; /* AAD or msg/mask buffer */ \ + unsigned off; /* Crossover point in buffer */ \ +} pre##_ccmctx; \ + \ +extern const octet pre##_ccmnoncesz[], pre##_ccmtagsz[]; \ + \ +/* --- @pre_ccminit@ --- * \ + * \ + * Arguments: @pre_ccmctx *aad@ = pointer to CCM context \ + * @const pre_ctx *k@ = pointer to key material \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of the nonce \ + * @size_t hsz@ = size of the AAD \ + * @size_t msz@ = size of the message/ciphertext \ + * @size_t tsz@ = size of the tag to produce \ + * \ + * Returns: Zero on success; nonzero if the parameters are invalid. \ + * \ + * Use: Initialize an CCM operation context with a given key. \ + * \ + * The original key needn't be kept around any more. \ + */ \ + \ +extern int pre##_ccminit(pre##_ccmctx */*ctx*/, \ + const pre##_ctx */*k*/, \ + const void */*n*/, size_t /*nsz*/, \ + size_t /*hsz*/, size_t /*msz*/, \ + size_t /*tsz*/); \ + \ +/* --- @pre_ccmreinit@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to CCM context \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * @size_t hsz@ = size of the AAD \ + * @size_t msz@ = size of the message/ciphertext \ + * @size_t tsz@ = size of the tag to produce \ + * \ + * Returns: Zero on success; nonzero if the parameters are invalid. \ + * \ + * Use: Reinitialize an CCM operation context, changing the \ + * nonce and/or other parameters. \ + */ \ + \ +extern int pre##_ccmreinit(pre##_ccmctx */*ctx*/, \ + const void */*n*/, size_t /*nsz*/, \ + size_t /*hsz*/, size_t /*msz*/, \ + size_t /*tsz*/); \ + \ +/* --- @pre_ccmaadhash@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to AAD context \ + * @const void *p@ = pointer to AAD material \ + * @size_t sz@ = length of AAD material \ + * \ + * Returns: --- \ + * \ + * Use: Feeds AAD into the context. This must be done before \ + * any of the message/ciphertext is processed because CCM \ + * is really annoying like that. \ + */ \ + \ +extern void pre##_ccmaadhash(pre##_ccmctx */*ctx*/, \ + const void */*p*/, size_t /*sz*/); \ + \ +/* --- @pre_ccmencrypt@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to CCM operation context \ + * @const void *src@ = pointer to plaintext message chunk \ + * @size_t sz@ = size of the plaintext \ + * @buf *dst@ = a buffer to write the ciphertext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Encrypts a chunk of a plaintext message, writing a \ + * chunk of ciphertext to the output buffer and updating \ + * the operation state. \ + * \ + * For CCM, we always write a ciphertext chunk the same \ + * size as the plaintext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +extern int pre##_ccmencrypt(pre##_ccmctx */*ctx*/, \ + const void */*src*/, size_t /*sz*/, \ + buf */*dst*/); \ + \ +/* --- @pre_ccmdecrypt@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to CCM operation context \ + * @const void *src@ = pointer to ciphertext message chunk \ + * @size_t sz@ = size of the ciphertext \ + * @buf *dst@ = a buffer to write the plaintext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Decrypts a chunk of a ciphertext message, writing a \ + * chunk of plaintext to the output buffer and updating \ + * the operation state. \ + * \ + * For CCM, we always write a plaintext chunk the same \ + * size as the ciphertext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +extern int pre##_ccmdecrypt(pre##_ccmctx */*ctx*/, \ + const void */*src*/, size_t /*sz*/, \ + buf */*dst*/); \ + \ +/* --- @pre_ccmencryptdone@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to an CCM context \ + * @buf *dst@ = buffer for remaining ciphertext \ + * @void *tag@ = where to write the tag \ + * @size_t tsz@ = length of tag to store \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Completes an CCM encryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. CCM doesn't buffer ciphertext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +extern int pre##_ccmencryptdone(pre##_ccmctx */*ctx*/, buf */*dst*/, \ + void */*tag*/, size_t /*tsz*/); \ + \ +/* --- @pre_ccmdecryptdone@ --- * \ + * \ + * Arguments: @pre_ccmctx *ctx@ = pointer to an CCM context \ + * @buf *dst@ = buffer for remaining plaintext \ + * @const void *tag@ = tag to verify \ + * @size_t tsz@ = length of tag \ + * \ + * Returns: @+1@ for complete success; @0@ if tag verification \ + * failed; @-1@ for other kinds of errors. \ + * \ + * Use: Completes an CCM decryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. CCM doesn't buffer plaintext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +extern int pre##_ccmdecryptdone(pre##_ccmctx */*ctx*/, buf */*dst*/, \ + const void */*tag*/, size_t /*tsz*/); \ + \ +/* --- Generic AEAD interface --- */ \ + \ +extern const gcaead pre##_ccm; + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/cfb-def.h b/symm/cfb-def.h index 78aa6d98..303bc9fd 100644 --- a/symm/cfb-def.h +++ b/symm/cfb-def.h @@ -59,6 +59,10 @@ # include "paranoia.h" #endif +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + /*----- Macros ------------------------------------------------------------*/ /* --- @CFB_DEF@ --- * @@ -90,8 +94,9 @@ void pre##_cfbgetiv(const pre##_cfbctx *ctx, void *iv) \ octet *p = iv; \ unsigned off = ctx->off; \ unsigned rest = PRE##_BLKSZ - off; \ - memcpy(p, ctx->iv + off, rest); \ - memcpy(p + rest, ctx->iv, off); \ + \ + memcpy(p, ctx->b + off, rest); \ + memcpy(p + rest, ctx->b, off); \ } \ \ /* --- @pre_cfbsetiv@ --- * \ @@ -105,10 +110,7 @@ void pre##_cfbgetiv(const pre##_cfbctx *ctx, void *iv) \ */ \ \ void pre##_cfbsetiv(pre##_cfbctx *ctx, const void *iv) \ -{ \ - memcpy(ctx->iv, iv, PRE##_BLKSZ); \ - ctx->off = PRE##_BLKSZ; \ -} \ + { memcpy(ctx->b, iv, PRE##_BLKSZ); ctx->off = 0; } \ \ /* --- @pre_cfbbdry@ --- * \ * \ @@ -122,12 +124,13 @@ void pre##_cfbsetiv(pre##_cfbctx *ctx, const void *iv) \ \ void pre##_cfbbdry(pre##_cfbctx *ctx) \ { \ - uint32 niv[PRE##_BLKSZ / 4]; \ - BLKC_LOAD(PRE, niv, ctx->iv); \ - pre##_eblk(&ctx->ctx, niv, niv); \ - BLKC_STORE(PRE, ctx->iv, niv); \ - ctx->off = PRE##_BLKSZ; \ - BURN(niv); \ + uint32 t[PRE##_BLKSZ/4]; \ + \ + BLKC_LOAD(PRE, t, ctx->b); \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + ctx->off = 0; \ + BURN(t); \ } \ \ /* --- @pre_cfbsetkey@ --- * \ @@ -141,10 +144,7 @@ void pre##_cfbbdry(pre##_cfbctx *ctx) \ */ \ \ void pre##_cfbsetkey(pre##_cfbctx *ctx, const pre##_ctx *k) \ -{ \ - ctx->ctx = *k; \ - ctx->off = PRE##_BLKSZ; \ -} \ + { ctx->ctx = *k; ctx->off = 0; } \ \ /* --- @pre_cfbinit@ --- * \ * \ @@ -163,10 +163,11 @@ void pre##_cfbsetkey(pre##_cfbctx *ctx, const pre##_ctx *k) \ */ \ \ void pre##_cfbinit(pre##_cfbctx *ctx, \ - const void *key, size_t sz, \ - const void *iv) \ + const void *key, size_t sz, \ + const void *iv) \ { \ static const octet zero[PRE##_BLKSZ] = { 0 }; \ + \ pre##_init(&ctx->ctx, key, sz); \ pre##_cfbsetiv(ctx, iv ? iv : zero); \ } \ @@ -185,75 +186,75 @@ void pre##_cfbinit(pre##_cfbctx *ctx, \ * sensitive to block boundaries. \ */ \ \ +static const rsvr_policy pre##_cfbpolicy = { 0, PRE##_BLKSZ, PRE##_BLKSZ }; \ + \ void pre##_cfbencrypt(pre##_cfbctx *ctx, \ - const void *src, void *dest, \ - size_t sz) \ + const void *src, void *dest, \ + size_t sz) \ { \ + rsvr_plan plan; \ const octet *s = src; \ - octet *d = dest; \ - unsigned off = ctx->off; \ - \ - /* --- Empty blocks are trivial --- */ \ - \ - if (!sz) \ - return; \ - \ - /* --- If I can deal with the block from my buffer, do that --- */ \ - \ - if (sz < PRE##_BLKSZ - off) \ - goto small; \ - \ - /* --- Finish off what's left in my buffer --- */ \ - \ - while (off < PRE##_BLKSZ) { \ - register octet x = *s++; \ - ctx->iv[off] ^= x; \ - if (d) *d++ = ctx->iv[off]; \ - off++; \ - sz--; \ + octet *d = dest, *p; \ + uint32 t[PRE##_BLKSZ/4]; \ + octet y; \ + \ + /* Construct a plan and prepare to follow through. */ \ + rsvr_mkplan(&plan, &pre##_cfbpolicy, ctx->off, sz); \ + BLKC_LOAD(PRE, t, ctx->b); \ + \ + /* Initial portion, fulfilled from the buffer. If the chunk is small \ + * enough, then this will be the only portion. If the buffer is \ + * currently empty, then we must prepare it. \ + */ \ + if (plan.head) { \ + if (!ctx->off) { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + } \ + p = ctx->b + ctx->off; ctx->off += plan.head; \ + if (s) while (plan.head--) { y = *s++ ^ *p; *p++ = y; if (d) *d++ = y; } \ + else if (d) { memcpy(d, p, plan.head); d += plan.head; } \ + BLKC_LOAD(PRE, t, ctx->b); \ } \ \ - /* --- Main encryption loop --- */ \ - \ - { \ - uint32 iv[PRE##_BLKSZ / 4]; \ - BLKC_LOAD(PRE, iv, ctx->iv); \ - \ - for (;;) { \ - pre##_eblk(&ctx->ctx, iv, iv); \ - if (sz < PRE##_BLKSZ) \ - break; \ - if (s) { \ - BLKC_XLOAD(PRE, iv, s); \ - s += PRE##_BLKSZ; \ - } \ - if (d) { \ - BLKC_STORE(PRE, d, iv); \ - d += PRE##_BLKSZ; \ - } \ - sz -= PRE##_BLKSZ; \ + /* If the buffer is all used, then reset it ready for next time. */ \ + ctx->off -= plan.from_rsvr; \ + \ + /* Handle multiple whole blocks. */ \ + if (!d) { \ + if (!s) while (plan.from_input) { \ + pre##_eblk(&ctx->ctx, t, t); \ + plan.from_input -= PRE##_BLKSZ; \ + } else while (plan.from_input) { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_XLOAD(PRE, t, s); s += PRE##_BLKSZ; \ + plan.from_input -= PRE##_BLKSZ; \ + } \ + } else { \ + if (!s) while (plan.from_input) { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, d, t); d += PRE##_BLKSZ; \ + plan.from_input -= PRE##_BLKSZ; \ + } else while (plan.from_input) { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_XLOAD(PRE, t, s); s += PRE##_BLKSZ; \ + BLKC_STORE(PRE, d, t); d += PRE##_BLKSZ; \ + plan.from_input -= PRE##_BLKSZ; \ } \ - off = 0; \ - BLKC_STORE(PRE, ctx->iv, iv); \ } \ \ - /* --- Tidying up the tail end --- */ \ - \ - if (sz) { \ - small: \ - do { \ - register octet x = *s++; \ - ctx->iv[off] ^= x; \ - if (d) *d++ = ctx->iv[off]; \ - off++; \ - sz--; \ - } while (sz); \ + /* Final portion. Note that the buffer must be empty if there is a \ + * tail, since otherwise the input data would have been part of the \ + * head portion instad. */ \ + if (!plan.tail) \ + BLKC_STORE(PRE, ctx->b, t); \ + else { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + p = ctx->b; ctx->off += plan.tail; \ + if (s) while (plan.tail--) { y = *s++ ^ *p; *p++ = y; if (d) *d++ = y; } \ + else if (d) { memcpy(d, p, plan.tail); d += plan.tail; } \ } \ - \ - /* --- Done --- */ \ - \ - ctx->off = off; \ - return; \ } \ \ /* --- @pre_cfbdecrypt@ --- * \ @@ -271,70 +272,58 @@ void pre##_cfbencrypt(pre##_cfbctx *ctx, \ */ \ \ void pre##_cfbdecrypt(pre##_cfbctx *ctx, \ - const void *src, void *dest, \ - size_t sz) \ + const void *src, void *dest, \ + size_t sz) \ { \ + rsvr_plan plan; \ const octet *s = src; \ - octet *d = dest; \ - unsigned off = ctx->off; \ - \ - /* --- Empty blocks are trivial --- */ \ - \ - if (!sz) \ - return; \ - \ - /* --- If I can deal with the block from my buffer, do that --- */ \ - \ - if (sz < PRE##_BLKSZ - off) \ - goto small; \ - \ - /* --- Finish off what's left in my buffer --- */ \ - \ - while (off < PRE##_BLKSZ) { \ - register octet x = *s++; \ - *d++ = ctx->iv[off] ^ x; \ - ctx->iv[off++] = x; \ - sz--; \ - } \ - \ - /* --- Main encryption loop --- */ \ - \ - { \ - uint32 iv[PRE##_BLKSZ / 4]; \ - BLKC_LOAD(PRE, iv, ctx->iv); \ - \ - for (;;) { \ - uint32 x[PRE##_BLKSZ / 4]; \ - pre##_eblk(&ctx->ctx, iv, iv); \ - if (sz < PRE##_BLKSZ) \ - break; \ - BLKC_LOAD(PRE, x, s); \ - BLKC_XSTORE(PRE, d, iv, x); \ - BLKC_MOVE(PRE, iv, x); \ - s += PRE##_BLKSZ; \ - d += PRE##_BLKSZ; \ - sz -= PRE##_BLKSZ; \ + octet *d = dest, *p; \ + uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ/4]; \ + octet y; \ + \ + /* Construct a plan and prepare to follow through. */ \ + rsvr_mkplan(&plan, &pre##_cfbpolicy, ctx->off, sz); \ + BLKC_LOAD(PRE, t, ctx->b); \ + \ + /* Initial portion, fulfilled from the buffer. If the chunk is small \ + * enough, then this will be the only portion. If the buffer is \ + * currently empty, then we must prepare it. \ + */ \ + if (plan.head) { \ + if (!ctx->off) { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, ctx->b, t); \ } \ - off = 0; \ - BLKC_STORE(PRE, ctx->iv, iv); \ + p = ctx->b + ctx->off; \ + ctx->off += plan.head; \ + while (plan.head--) { y = *s++; *d++ = y ^ *p; *p++ = y; } \ + BLKC_LOAD(PRE, t, ctx->b); \ } \ \ - /* --- Tidying up the tail end --- */ \ + /* If the buffer is all used, then reset it ready for next time. */ \ + ctx->off -= plan.from_rsvr; \ \ - if (sz) { \ - small: \ - do { \ - register octet x = *s++; \ - *d++ = ctx->iv[off] ^ x; \ - ctx->iv[off++] = x; \ - sz--; \ - } while (sz); \ + /* Handle multiple whole blocks. */ \ + while (plan.from_input) { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_LOAD(PRE, u, s); s += PRE##_BLKSZ; \ + BLKC_XSTORE(PRE, d, t, u); d += PRE##_BLKSZ; \ + BLKC_MOVE(PRE, t, u); \ + plan.from_input -= PRE##_BLKSZ; \ } \ \ - /* --- Done --- */ \ - \ - ctx->off = off; \ - return; \ + /* Final portion. Note that the buffer must be empty if there is a \ + * tail, since otherwise the input data would have been part of the \ + * head portion instad. */ \ + if (!plan.tail) \ + BLKC_STORE(PRE, ctx->b, t); \ + else { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + p = ctx->b; \ + ctx->off += plan.tail; \ + while (plan.tail--) { y = *s++; *d++ = y ^ *p; *p++ = y; } \ + } \ } \ \ /* --- Generic cipher interface --- */ \ @@ -355,35 +344,19 @@ static gcipher *ginit(const void *k, size_t sz) \ } \ \ static void gencrypt(gcipher *c, const void *s, void *t, size_t sz) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_cfbencrypt(&g->k, s, t, sz); \ -} \ + { gctx *g = (gctx *)c; pre##_cfbencrypt(&g->k, s, t, sz); } \ \ static void gdecrypt(gcipher *c, const void *s, void *t, size_t sz) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_cfbdecrypt(&g->k, s, t, sz); \ -} \ + { gctx *g = (gctx *)c; pre##_cfbdecrypt(&g->k, s, t, sz); } \ \ static void gdestroy(gcipher *c) \ -{ \ - gctx *g = (gctx *)c; \ - BURN(*g); \ - S_DESTROY(g); \ -} \ + { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); } \ \ static void gsetiv(gcipher *c, const void *iv) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_cfbsetiv(&g->k, iv); \ -} \ + { gctx *g = (gctx *)c; pre##_cfbsetiv(&g->k, iv); } \ \ static void gbdry(gcipher *c) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_cfbbdry(&g->k); \ -} \ + { gctx *g = (gctx *)c; pre##_cfbbdry(&g->k); } \ \ static const gcipher_ops gops = { \ &pre##_cfb, \ @@ -403,9 +376,7 @@ CFB_TESTX(PRE, pre, name, fname) #ifdef TEST_RIG -#include - -#include "daftstory.h" +#include "modes-test.h" /* --- @CFB_TEST@ --- * * @@ -416,85 +387,27 @@ CFB_TESTX(PRE, pre, name, fname) #define CFB_TESTX(PRE, pre, name, fname) \ \ -/* --- Initial plaintext for the test --- */ \ - \ -static const octet text[] = TEXT; \ - \ -/* --- Key and IV to use --- */ \ +static pre##_ctx key; \ +static pre##_cfbctx ctx; \ \ -static const octet key[] = KEY; \ -static const octet iv[] = IV; \ +static void pre##_cfb_test_setup(const octet *k, size_t ksz) \ + { pre##_init(&key, k, ksz); pre##_cfbsetkey(&ctx, &key); } \ \ -/* --- Buffers for encryption and decryption output --- */ \ +static void pre##_cfb_test_reset(const octet *iv) \ + { pre##_cfbsetiv(&ctx, iv); } \ \ -static octet ct[sizeof(text)]; \ -static octet pt[sizeof(text)]; \ +static void pre##_cfb_test_enc(const octet *s, octet *d, size_t sz) \ + { pre##_cfbencrypt(&ctx, s, d, sz); } \ \ -static void hexdump(const octet *p, size_t sz, size_t off) \ -{ \ - const octet *q = p + sz; \ - for (sz = 0; p < q; p++, sz++) { \ - printf("%02x", *p); \ - if ((off + sz + 1) % PRE##_BLKSZ == 0) \ - putchar(':'); \ - } \ -} \ +static void pre##_cfb_test_dec(const octet *s, octet *d, size_t sz) \ + { pre##_cfbdecrypt(&ctx, s, d, sz); } \ \ -int main(void) \ +int main(int argc, char *argv[]) \ { \ - size_t sz = 0, rest; \ - pre##_cfbctx ctx; \ - int status = 0; \ - int done = 0; \ - pre##_ctx k; \ - \ - size_t keysz = PRE##_KEYSZ ? \ - PRE##_KEYSZ : strlen((const char *)key); \ - \ - fputs(name "-cfb: ", stdout); \ - \ - pre##_init(&k, key, keysz); \ - pre##_cfbsetkey(&ctx, &k); \ - \ - while (sz <= sizeof(text)) { \ - rest = sizeof(text) - sz; \ - memcpy(ct, text, sizeof(text)); \ - pre##_cfbsetiv(&ctx, iv); \ - pre##_cfbencrypt(&ctx, ct, ct, sz); \ - pre##_cfbencrypt(&ctx, ct + sz, ct + sz, rest); \ - memcpy(pt, ct, sizeof(text)); \ - pre##_cfbsetiv(&ctx, iv); \ - pre##_cfbdecrypt(&ctx, pt, pt, rest); \ - pre##_cfbdecrypt(&ctx, pt + rest, pt + rest, sz); \ - if (memcmp(pt, text, sizeof(text)) == 0) { \ - done++; \ - if (sizeof(text) < 40 || done % 8 == 0) \ - fputc('.', stdout); \ - if (done % 480 == 0) \ - fputs("\n\t", stdout); \ - fflush(stdout); \ - } else { \ - printf("\nError (sz = %lu)\n", (unsigned long)sz); \ - status = 1; \ - printf("\tplaintext = "); hexdump(text, sz, 0); \ - printf(", "); hexdump(text + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\tciphertext = "); hexdump(ct, sz, 0); \ - printf(", "); hexdump(ct + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\trecovered text = "); hexdump(pt, sz, 0); \ - printf(", "); hexdump(pt + sz, rest, sz); \ - fputc('\n', stdout); \ - fputc('\n', stdout); \ - } \ - if (sz < 63) \ - sz++; \ - else \ - sz += 9; \ - } \ - \ - fputs(status ? " failed\n" : " ok\n", stdout); \ - return (status); \ + return test_encmode(fname "-cfb", PRE##_KEYSZ, PRE##_BLKSZ, 1, 0, \ + pre##_cfb_test_setup, pre##_cfb_test_reset, \ + pre##_cfb_test_enc, pre##_cfb_test_dec, \ + argc, argv); \ } #else diff --git a/symm/cfb.h b/symm/cfb.h index c357115c..ddaa5fd3 100644 --- a/symm/cfb.h +++ b/symm/cfb.h @@ -58,7 +58,7 @@ typedef struct pre##_cfbctx { \ pre##_ctx ctx; /* Underlying cipher context */ \ unsigned off; /* Offset into @iv@ buffer */ \ - octet iv[PRE##_BLKSZ]; /* Previous ciphertext or IV */ \ + octet b[PRE##_BLKSZ]; /* Previous ciphertext or IV */ \ } pre##_cfbctx; \ \ /* --- @pre_cfbgetiv@ --- * \ diff --git a/symm/chacha-arm-neon.S b/symm/chacha-arm-neon.S index af53cfd3..a900db76 100644 --- a/symm/chacha-arm-neon.S +++ b/symm/chacha-arm-neon.S @@ -25,18 +25,19 @@ /// MA 02111-1307, USA. ///-------------------------------------------------------------------------- -/// External definitions. +/// Preliminaries. #include "config.h" #include "asm-common.h" -///-------------------------------------------------------------------------- -/// Main.code. - .arch armv7-a .fpu neon + .text +///-------------------------------------------------------------------------- +/// Main.code. + FUNC(chacha_core_arm_neon) // Arguments are in registers. diff --git a/symm/chacha-arm64.S b/symm/chacha-arm64.S index a423e9e5..61ac51a1 100644 --- a/symm/chacha-arm64.S +++ b/symm/chacha-arm64.S @@ -25,17 +25,18 @@ /// MA 02111-1307, USA. ///-------------------------------------------------------------------------- -/// External definitions. +/// Preliminaries. #include "config.h" #include "asm-common.h" -///-------------------------------------------------------------------------- -/// Main.code. - .arch armv8-a + .text +///-------------------------------------------------------------------------- +/// Main.code. + FUNC(chacha_core_arm64) // Arguments are in registers. diff --git a/symm/chacha-poly1305.c b/symm/chacha-poly1305.c new file mode 100644 index 00000000..657987ee --- /dev/null +++ b/symm/chacha-poly1305.c @@ -0,0 +1,86 @@ +/* -*-c-*- + * + * AEAD schemes based on ChaCha and Poly1305 + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "chacha.h" +#include "latinpoly-def.h" + +/*----- Main code ---------------------------------------------------------*/ + +LATINPOLY_DEF(chacha20, chacha, "chacha20") +LATINPOLY_DEF(chacha12, chacha, "chacha12") +LATINPOLY_DEF(chacha8, chacha, "chacha8") + +/*----- Test rig ----------------------------------------------------------*/ + +#ifdef TEST_RIG + +#include +#include +#include "latinpoly-test.h" + +static int check_chacha20_poly1305(dstr *v) + { return latinpoly_test(&chacha20_poly1305, v); } +static int check_chacha12_poly1305(dstr *v) + { return latinpoly_test(&chacha12_poly1305, v); } +static int check_chacha8_poly1305(dstr *v) + { return latinpoly_test(&chacha8_poly1305, v); } +static int check_chacha20_naclbox(dstr *v) + { return latinpoly_test(&chacha20_naclbox, v); } +static int check_chacha12_naclbox(dstr *v) + { return latinpoly_test(&chacha12_naclbox, v); } +static int check_chacha8_naclbox(dstr *v) + { return latinpoly_test(&chacha8_naclbox, v); } + +static const test_chunk tests[] = { + { "chacha20-poly1305", check_chacha20_poly1305, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { "chacha12-poly1305", check_chacha12_poly1305, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { "chacha8-poly1305", check_chacha8_poly1305, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { "chacha20-naclbox", check_chacha20_naclbox, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { "chacha12-naclbox", check_chacha12_naclbox, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { "chacha8-naclbox", check_chacha8_naclbox, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { 0, 0, { 0 } } +#undef TEST +}; + +int main(int argc, char *argv[]) +{ + ego(argv[0]); + test_run(argc, argv, tests, SRCDIR"/t/chacha"); + return (0); +} + +#endif + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/symm/chacha-x86ish-sse2.S b/symm/chacha-x86ish-sse2.S index 2dab283b..3fb623af 100644 --- a/symm/chacha-x86ish-sse2.S +++ b/symm/chacha-x86ish-sse2.S @@ -25,16 +25,24 @@ /// MA 02111-1307, USA. ///-------------------------------------------------------------------------- -/// External definitions. +/// Preliminaries. #include "config.h" #include "asm-common.h" + .text + ///-------------------------------------------------------------------------- /// Main code. - .arch pentium4 - .text +FUNC(chacha_core_x86ish_avx) + .arch .avx + vzeroupper + endprologue + // drop through... +ENDFUNC + + .arch pentium4 FUNC(chacha_core_x86ish_sse2) @@ -61,7 +69,7 @@ FUNC(chacha_core_x86ish_sse2) # define SAVE3 [esp] pushreg ebp - setfp ebp + setfp sub esp, 16 mov IN, [ebp + 12] mov OUT, [ebp + 16] @@ -156,9 +164,9 @@ FUNC(chacha_core_x86ish_sse2) // c += d; b ^= c; b <<<= 7 paddd xmm2, xmm3 - pshufd xmm3, xmm3, SHUF(2, 1, 0, 3) + pshufd xmm3, xmm3, SHUF(3, 0, 1, 2) pxor xmm1, xmm2 - pshufd xmm2, xmm2, SHUF(1, 0, 3, 2) + pshufd xmm2, xmm2, SHUF(2, 3, 0, 1) movdqa xmm4, xmm1 pslld xmm1, 7 psrld xmm4, 25 @@ -176,7 +184,7 @@ FUNC(chacha_core_x86ish_sse2) // // The shuffles have quite high latency, so they've mostly been // pushed upwards. The remaining one can't be moved, though. - pshufd xmm1, xmm1, SHUF(0, 3, 2, 1) + pshufd xmm1, xmm1, SHUF(1, 2, 3, 0) // Apply the diagonal quarterround to each of the columns // simultaneously. @@ -207,9 +215,9 @@ FUNC(chacha_core_x86ish_sse2) // c += d; b ^= c; b <<<= 7 paddd xmm2, xmm3 - pshufd xmm3, xmm3, SHUF(0, 3, 2, 1) + pshufd xmm3, xmm3, SHUF(1, 2, 3, 0) pxor xmm1, xmm2 - pshufd xmm2, xmm2, SHUF(1, 0, 3, 2) + pshufd xmm2, xmm2, SHUF(2, 3, 0, 1) movdqa xmm4, xmm1 pslld xmm1, 7 psrld xmm4, 25 @@ -218,7 +226,7 @@ FUNC(chacha_core_x86ish_sse2) // Finally, finish off undoing the transpose, and we're done for this // doubleround. Again, most of this was done above so we don't have // to wait for the shuffles. - pshufd xmm1, xmm1, SHUF(2, 1, 0, 3) + pshufd xmm1, xmm1, SHUF(3, 0, 1, 2) // Decrement the loop counter and see if we should go round again. sub NR, 2 diff --git a/symm/chacha.c b/symm/chacha.c index 71522003..983f58c7 100644 --- a/symm/chacha.c +++ b/symm/chacha.c @@ -41,6 +41,7 @@ #include "grand.h" #include "keysz.h" #include "paranoia.h" +#include "rsvr.h" /*----- Global variables --------------------------------------------------*/ @@ -72,6 +73,7 @@ static void simple_core(unsigned r, const chacha_matrix src, #if CPUFAM_X86 || CPUFAM_AMD64 extern core__functype chacha_core_x86ish_sse2; +extern core__functype chacha_core_x86ish_avx; #endif #if CPUFAM_ARMEL @@ -85,6 +87,8 @@ extern core__functype chacha_core_arm64; static core__functype *pick_core(void) { #if CPUFAM_X86 || CPUFAM_AMD64 + DISPATCH_PICK_COND(chacha_core, chacha_core_x86ish_avx, + cpu_feature_p(CPUFEAT_X86_AVX)); DISPATCH_PICK_COND(chacha_core, chacha_core_x86ish_sse2, cpu_feature_p(CPUFEAT_X86_SSE2)); #endif @@ -149,6 +153,8 @@ static void populate(chacha_matrix a, const void *key, size_t ksz) /*----- ChaCha implementation ---------------------------------------------*/ +static const octet zerononce[XCHACHA_NONCESZ]; + /* --- @chacha_init@ --- * * * Arguments: @chacha_ctx *ctx@ = context to fill in @@ -164,8 +170,6 @@ static void populate(chacha_matrix a, const void *key, size_t ksz) void chacha_init(chacha_ctx *ctx, const void *key, size_t ksz, const void *nonce) { - static const octet zerononce[CHACHA_NONCESZ]; - populate(ctx->a, key, ksz); chacha_setnonce(ctx, nonce ? nonce : zerononce); } @@ -221,7 +225,7 @@ void chacha_seek(chacha_ctx *ctx, unsigned long i) void chacha_seeku64(chacha_ctx *ctx, kludge64 i) { ctx->a[12] = LO64(i); ctx->a[13] = HI64(i); - ctx->bufi = CHACHA_OUTSZ; + ctx->off = CHACHA_OUTSZ; } void chacha_seek_ietf(chacha_ctx *ctx, uint32 i) @@ -261,6 +265,8 @@ uint32 chacha_tell_ietf(chacha_ctx *ctx) * to @dest@. */ +static const rsvr_policy policy = { 0, CHACHA_OUTSZ, CHACHA_OUTSZ }; + #define CHACHA_ENCRYPT(r, ctx, src, dest, sz) \ chacha##r##_encrypt(ctx, src, dest, sz) #define DEFENCRYPT(r) \ @@ -270,41 +276,40 @@ uint32 chacha_tell_ietf(chacha_ctx *ctx) chacha_matrix b; \ const octet *s = src; \ octet *d = dest; \ - size_t n; \ + rsvr_plan plan; \ kludge64 pos, delta; \ \ - SALSA20_OUTBUF(ctx, d, s, sz); \ - if (!sz) return; \ - \ - if (!dest) { \ - n = sz/CHACHA_OUTSZ; \ - pos = chacha_tellu64(ctx); \ - ASSIGN64(delta, n); \ - ADD64(pos, pos, delta); \ - chacha_seeku64(ctx, pos); \ - sz = sz%CHACHA_OUTSZ; \ - } else if (!src) { \ - while (sz >= CHACHA_OUTSZ) { \ - core(r, ctx->a, b); \ - CHACHA_STEP(ctx->a); \ - SALSA20_GENFULL(b, d); \ - sz -= CHACHA_OUTSZ; \ + rsvr_mkplan(&plan, &policy, ctx->off, sz); \ + \ + if (plan.head) { \ + if (!ctx->off) { \ + core(r, ctx->a, b); CHACHA_STEP(ctx->a); \ + SALSA20_PREPBUF(ctx, b); \ } \ - } else { \ - while (sz >= CHACHA_OUTSZ) { \ - core(r, ctx->a, b); \ - CHACHA_STEP(ctx->a); \ - SALSA20_MIXFULL(b, d, s); \ - sz -= CHACHA_OUTSZ; \ + SALSA20_OUTBUF(ctx, d, s, plan.head); \ + } \ + \ + ctx->off -= plan.from_rsvr; \ + \ + if (!d) { \ + if (plan.from_input) { \ + pos = chacha_tellu64(ctx); \ + ASSIGN64(delta, plan.from_input/SALSA20_OUTSZ); \ + ADD64(pos, pos, delta); \ + chacha_seeku64(ctx, pos); \ } \ + } else if (!s) while (plan.from_input) { \ + core(r, ctx->a, b); CHACHA_STEP(ctx->a); \ + SALSA20_GENFULL(b, d); plan.from_input -= CHACHA_OUTSZ; \ + } else while (plan.from_input) { \ + core(r, ctx->a, b); CHACHA_STEP(ctx->a); \ + SALSA20_MIXFULL(b, d, s); plan.from_input -= CHACHA_OUTSZ; \ } \ \ - if (sz) { \ - core(r, ctx->a, b); \ - CHACHA_STEP(ctx->a); \ + if (plan.tail) { \ + core(r, ctx->a, b); CHACHA_STEP(ctx->a); \ SALSA20_PREPBUF(ctx, b); \ - SALSA20_OUTBUF(ctx, d, s, sz); \ - assert(!sz); \ + SALSA20_OUTBUF(ctx, d, s, plan.tail); \ } \ } CHACHA_VARS(DEFENCRYPT) @@ -400,8 +405,6 @@ CHACHA_VARS(DEFHCHACHA) void XCHACHA_INIT(r, XCHACHA_CTX(r) *ctx, \ const void *key, size_t ksz, const void *nonce) \ { \ - static const octet zerononce[XCHACHA_NONCESZ]; \ - \ populate(ctx->k, key, ksz); \ ctx->s.a[ 0] = CHACHA_A256; \ ctx->s.a[ 1] = CHACHA_B256; \ diff --git a/symm/chacha.h b/symm/chacha.h index 994cfa2b..6c380dca 100644 --- a/symm/chacha.h +++ b/symm/chacha.h @@ -64,8 +64,8 @@ typedef uint32 chacha_matrix[16]; typedef struct chacha_ctx { chacha_matrix a; - octet buf[CHACHA_OUTSZ]; - size_t bufi; + octet b[CHACHA_OUTSZ]; + unsigned off; } chacha_ctx; #define XCHACHA_DEFCTX(name) \ @@ -89,8 +89,8 @@ XCHACHA_DEFCTX(xchacha8_ctx); */ extern void chacha_init(chacha_ctx */*ctx*/, - const void */*key*/, size_t /*ksz*/, - const void */*nonce*/); + const void */*key*/, size_t /*ksz*/, + const void */*nonce*/); /* --- @chacha_setnonce{,_ietf}@ --- * * diff --git a/symm/cmac-def.h b/symm/cmac-def.h new file mode 100644 index 00000000..701d3b52 --- /dev/null +++ b/symm/cmac-def.h @@ -0,0 +1,406 @@ +/* -*-c-*- + * + * The CMAC message-authentication code + * + * (c) 2017 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef CATACOMB_CMAC_DEF_H +#define CATACOMB_CMAC_DEF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +#ifndef CATACOMB_ARENA_H +# include "arena.h" +#endif + +#ifndef CATACOMB_BLKC_H +# include "blkc.h" +#endif + +#ifndef CATACOMB_GMAC_H +# include "gmac.h" +#endif + +#ifndef CATACOMB_PARANOIA_H +# include "paranoia.h" +#endif + +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + +/*----- Low-level OMAC definitions ----------------------------------------*/ + +/* --- @OMAC_BLOCK@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * @pre_ctx *k@ = pointer to expanded blockcipher key + * @uint32 *a@ = accumulator state to update + * @octet *p@ = pointer to input block to accumulate + * + * Use: Update the state @a@ from the input block @p@. + */ + +#define OMAC_BLOCK(PRE, pre, k, a, p) do { \ + pre##_ctx *_k = (k); uint32 *_a = (a); const octet *_pp = (p); \ + BLKC_XLOAD(PRE, _a, _pp); pre##_eblk(_k, _a, _a); \ +} while (0) + +/* --- @OMAC_DEF@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates low-level implementation for the OMAC message- + * authentication mode. + */ + +#define OMAC_DEF(PRE, pre) \ + \ +/* Buffering policy for OMAC. */ \ +const rsvr_policy pre##_omacpolicy = \ + { RSVRF_FULL, PRE##_BLKSZ, PRE##_BLKSZ }; \ + \ +/* --- @pre_omacmasks@ --- * \ + * \ + * Arguments: @pre_ctx *k@ = pointer to expanded blockcipher key \ + * @uint32 *m0, *m1@ = buffers to store the masks \ + * \ + * Returns: --- \ + * \ + * Use: Initialize the OMAC masks. The mask buffers are \ + * @PRE_BLKSZ/4@ words long. The mmask @m0@ is applied to \ + * messages which are a whole number of blocks long; @m1@ \ + * is applied to messages with an incomplete final block, \ + * following the 10* padding. \ + */ \ + \ +void pre##_omacmasks(pre##_ctx *k, uint32 *m0, uint32 *m1) \ +{ \ + uint32 t[PRE##_BLKSZ/4]; \ + \ + BLKC_ZERO(PRE, t); pre##_eblk(k, t, t); \ + BLKC_BLSHIFT(PRE, IRRED, m0, t); \ + BLKC_BLSHIFT(PRE, IRRED, m1, m0); \ +} \ + \ +/* --- @pre_omacdone@ --- * \ + * \ + * Arguments: @pre_ctx *k@ = pointer to expanded blockcipher key \ + * @const uint32 *m0, *m1@ = masks \ + * @uint32 *a@ = accumulator state to update \ + * @octet *p@ = pointer to input buffer (clobbered) \ + * @unsigned n@ = size of input buffer (no more than \ + * @PRE_BLKSZ@) \ + * \ + * Returns: --- \ + * \ + * Use: Update and finalize the OMAC hash state with the last \ + * few bytes of input. The final tag is left in @a@. \ + */ \ + \ +void pre##_omacdone(pre##_ctx *k, const uint32 *m0, const uint32 *m1, \ + uint32 *a, octet *p, unsigned n) \ +{ \ + /* Do any necessary padding and apply the appropriate mask to the \ + * accumulator. \ + */ \ + if (n == PRE##_BLKSZ) \ + BLKC_XMOVE(PRE, a, m0); \ + else { \ + p[n] = 0x80; memset(p + n + 1, 0, PRE##_BLKSZ - n - 1); \ + BLKC_XMOVE(PRE, a, m1); \ + } \ + \ + /* Fetch the buffer contents and cycle the block cipher one last \ + * time. \ + */ \ + BLKC_XLOAD(PRE, a, p); \ + pre##_eblk(k, a, a); \ +} + +/*----- Properly cooked CMAC ----------------------------------------------*/ + +/* --- @CMAC_DEF@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates an implementation for the CMAC message-authentication + * mode. + */ + +#define CMAC_DEF(PRE, pre) CMAC_DEFX(PRE, pre, #pre, #pre) + +#define CMAC_DEFX(PRE, pre, name, fname) \ + \ +OMAC_DEF(PRE, pre) \ + \ +/* --- @pre_cmacsetkey@ --- * \ + * \ + * Arguments: @pre_cmackey *key@ = pointer to CMAC key block \ + * @ocnst void *k@ = pointer to key material \ + * @size_t ksz@ = size of key material \ + * \ + * Returns: --- \ + * \ + * Use: Initializes a CMAC key. This can be used for several \ + * MAC operations. \ + */ \ + \ +void pre##_cmacsetkey(pre##_cmackey *key, const void *k, size_t ksz) \ +{ \ + pre##_init(&key->ctx, k, ksz); \ + pre##_omacmasks(&key->ctx, key->m0, key->m1); \ +} \ + \ +/* --- @pre##_cmacinit@ --- * \ + * \ + * Arguments: @pre_cmacctx *ctx@ = pointer to context block \ + * @pre_cmackey *k@ = key block \ + * \ + * Returns: --- \ + * \ + * Use: Initializes a CMAC context ready to process a message. \ + * It's not necessary to keep the key around. \ + */ \ + \ +void pre##_cmacinit(pre##_cmacctx *ctx, const pre##_cmackey *k) \ + { ctx->k = *k; ctx->off = 0; BLKC_ZERO(PRE, ctx->a); } \ + \ +/* --- @pre_cmachash@ --- * \ + * \ + * Arguments: @pre_cmacctx *ctx@ = pointer to CMAC context block \ + * @ocnst void *p@ = pointer to message buffer \ + * @size_t sz@ = size of message buffer \ + * \ + * Returns: --- \ + * \ + * Use: Hashes some input data. \ + */ \ + \ +void pre##_cmachash(pre##_cmacctx *ctx, const void *p, size_t sz) \ +{ \ + rsvr_state st; \ + const octet *q; \ + \ + rsvr_setup(&st, &pre##_omacpolicy, ctx->b, &ctx->off, p, sz); \ + RSVR_DO(&st) while ((q = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) \ + OMAC_BLOCK(PRE, pre, &ctx->k.ctx, ctx->a, q); \ +} \ + \ +/* --- @pre_cmacdone@ --- * \ + * \ + * Arguments: @pre_cmacctx *ctx@ = pointer to CMAC context block \ + * @void *t@ = where to write the tag \ + * \ + * Returns: --- \ + * \ + * Use: Finishes a MAC operation and produces the tag. The \ + * context is clobbered and can't be used for anything \ + * useful any more. \ + */ \ + \ +void pre##_cmacdone(pre##_cmacctx *ctx, void *t) \ +{ \ + pre##_omacdone(&ctx->k.ctx, ctx->k.m0, ctx->k.m1, \ + ctx->a, ctx->b, ctx->off); \ + BLKC_STORE(PRE, t, ctx->a); \ +} \ + \ +/* --- Generic MAC interface --- */ \ + \ +static const gmac_ops gkops; \ +static const ghash_ops gops; \ + \ +typedef struct gkctx { \ + gmac m; \ + pre##_cmackey k; \ +} gkctx; \ + \ +typedef struct gctx { \ + ghash h; \ + pre##_cmacctx c; \ + octet buf[PRE##_BLKSZ]; \ +} gctx; \ + \ +static ghash *gkinit(gmac *m) \ +{ \ + gkctx *gk = (gkctx *)m; \ + gctx *g = S_CREATE(gctx); \ + g->h.ops = &gops; \ + pre##_cmacinit(&g->c, &gk->k); \ + return (&g->h); \ +} \ + \ +static gmac *gkey(const void *k, size_t sz) \ +{ \ + gkctx *gk = S_CREATE(gkctx); \ + gk->m.ops = &gkops; \ + pre##_cmacsetkey(&gk->k, k, sz); \ + return (&gk->m); \ +} \ + \ +static void ghhash(ghash *h, const void *p, size_t sz) \ + { gctx *g = (gctx *)h; pre##_cmachash(&g->c, p, sz); } \ + \ +static octet *ghdone(ghash *h, void *buf) \ +{ \ + gctx *g = (gctx *)h; \ + if (!buf) buf = g->buf; \ + pre##_cmacdone(&g->c, buf); \ + return (buf); \ +} \ + \ +static ghash *ghcopy(ghash *h) \ +{ \ + gctx *g = (gctx *)h; \ + gctx *gg = S_CREATE(gctx); \ + memcpy(gg, g, sizeof(gctx)); \ + return (&gg->h); \ +} \ + \ +static void ghdestroy(ghash *h) \ + { gctx *g = (gctx *)h; BURN(*g); S_DESTROY(g); } \ + \ +static void gkdestroy(gmac *m) \ + { gkctx *gk = (gkctx *)m; BURN(*gk); S_DESTROY(gk); } \ + \ +static ghash *ghinit(void) \ +{ \ + assert(((void)"Attempt to instantiate an unkeyed MAC", 0)); \ + return (0); \ +} \ + \ +const gcmac pre##_cmac = \ + { name "-cmac", PRE##_BLKSZ, pre##_keysz, gkey }; \ +static const gmac_ops gkops = { &pre##_cmac, gkinit, gkdestroy }; \ +static const gchash gch = { name "-cmac", PRE##_BLKSZ, ghinit }; \ +static const ghash_ops gops = \ + { &gch, ghhash, ghdone, ghdestroy, ghcopy }; \ + \ +CMAC_TESTX(PRE, pre, name, fname) + +#define CMAC_TEST(PRE, pre) HMAC_TESTX(PRE, pre, #pre, #pre) + +/* --- @CMAC_TEST@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Standard test rig for CMAC functions. + */ + +#ifdef TEST_RIG + +#include + +#include +#include +#include + +#define CMAC_TESTX(PRE, pre, name, fname) \ + \ +static int macverify(dstr *v) \ +{ \ + pre##_cmacctx cctx; \ + pre##_cmackey ckey; \ + int ok = 1; \ + int i; \ + octet *p; \ + int szs[] = { 1, 7, 192, -1, 0 }, *ip; \ + size_t csz; \ + dstr d; \ + \ + dstr_create(&d); \ + dstr_ensure(&d, PRE##_BLKSZ); \ + d.len = PRE##_BLKSZ; \ + \ + pre##_cmacsetkey(&ckey, v[0].buf, v[0].len); \ + \ + for (ip = szs; *ip; ip++) { \ + i = *ip; \ + csz = v[1].len; \ + if (i == -1) \ + i = csz; \ + if (i > csz) \ + continue; \ + p = (octet *)v[1].buf; \ + pre##_cmacinit(&cctx, &ckey); \ + while (csz) { \ + if (i > csz) \ + i = csz; \ + pre##_cmachash(&cctx, p, i); \ + p += i; \ + csz -= i; \ + } \ + pre##_cmacdone(&cctx, d.buf); \ + if (memcmp(d.buf, v[2].buf, PRE##_BLKSZ) != 0) { \ + printf("\nfail:\n\tstep = %i\n\tkey = ", *ip); \ + type_hex.dump(&v[0], stdout); \ + fputs("\n\tinput = ", stdout); \ + type_hex.dump(&v[1], stdout); \ + fputs("\n\texpected = ", stdout); \ + type_hex.dump(&v[2], stdout); \ + fputs("\n\tcomputed = ", stdout); \ + type_hex.dump(&d, stdout); \ + putchar('\n'); \ + ok = 0; \ + } \ + } \ + \ + dstr_destroy(&d); \ + return (ok); \ +} \ + \ +static test_chunk macdefs[] = { \ + { name "-cmac", macverify, \ + { &type_hex, &type_hex, &type_hex, 0 } }, \ + { 0, 0, { 0 } } \ +}; \ + \ +int main(int argc, char *argv[]) \ +{ \ + ego(argv[0]); \ + test_run(argc, argv, macdefs, SRCDIR"/t/" fname); \ + return (0); \ +} + +#else +# define CMAC_TESTX(PRE, pre, name, fname) +#endif + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/cmac.h b/symm/cmac.h new file mode 100644 index 00000000..95b047e8 --- /dev/null +++ b/symm/cmac.h @@ -0,0 +1,210 @@ +/* -*-c-*- + * + * The CMAC message-authentication code + * + * (c) 2017 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Notes on CMAC -----------------------------------------------------* + * + * CMAC was designed in 2003 by Tetsu Iwata and Kaoru Kurosawa as a reliable + * general purpose message-authentication code based on CBC-MAC. CBC-MAC's + * deficiencies have been well known since at least 2000 when Bellare, + * Kilian, and Rogaway proved its security on constant-length messages. + * Black and Rogaway in 2000 described a number of three-key constructions + * for extending CBC-MAC's domain securely to arbitrary strings, culminating + * in a mode they named `XCBC', which uses a blockcipher key and two XOR + * masks. Iwata and Kurosawa's original proposal, named `OMAC', refined XCBC + * by deriving the masks from the key, producing a `one-key MAC'. Bellare, + * Rogaway, and Wagner slightly simplified the way the masks were derived + * when they used OMAC as a part of their EAX authenticated-encryption mode, + * and this change was adopted by NIST when they standardized OMAC, under the + * name `CMAC', in SP800-38B. + * + * NIST specify CMAC only for 64- and 128-bit blockciphers. This + * implementation extends it to other lengths in the obvious way. + */ + +#ifndef CATACOMB_CMAC_H +#define CATACOMB_CMAC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include + +#ifndef CATACOMB_GMAC_H +# include "gmac.h" +#endif + +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + +/*----- Low-level OMAC declarations ---------------------------------------*/ + +/* --- @OMAC_DECL@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Defines low-level implementation for the OMAC message- + * authentication mode. + */ + +#define OMAC_DECL(PRE, pre) \ + \ +/* Buffering policy for OMAC. */ \ +extern const rsvr_policy pre##_omacpolicy; \ + \ +/* --- @pre_omacmasks@ --- * \ + * \ + * Arguments: @pre_ctx *k@ = pointer to expanded blockcipher key \ + * @uint32 *m0, *m1@ = buffers to store the masks \ + * \ + * Returns: --- \ + * \ + * Use: Initialize the OMAC masks. The mask buffers are \ + * @PRE_BLKSZ/4@ words long. The mmask @m0@ is applied to \ + * messages which are a whole number of blocks long; @m1@ \ + * is applied to messages with an incomplete final block, \ + * following the 10* padding. \ + */ \ + \ +extern void pre##_omacmasks(pre##_ctx */*k*/, \ + uint32 */*m0*/, uint32 */*m1*/); \ + \ +/* --- @pre_omacdone@ --- * \ + * \ + * Arguments: @pre_ctx *k@ = pointer to expanded blockcipher key \ + * @const uint32 *m0, *m1@ = masks \ + * @uint32 *a@ = accumulator state to update \ + * @octet *p@ = pointer to input buffer (clobbered) \ + * @unsigned n@ = size of input buffer (no more than \ + * @PRE_BLKSZ@) \ + * \ + * Returns: --- \ + * \ + * Use: Update and finalize the OMAC hash state with the last \ + * few bytes of input. The final tag is left in @a@. \ + */ \ + \ +extern void pre##_omacdone(pre##_ctx */*k*/, \ + const uint32 */*m0*/, const uint32 */*m1*/, \ + uint32 */*a*/, octet */*p*/, unsigned /*n*/); + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @CMAC_DECL@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates declarations for CMAC message-authentication mode. + */ + +#define CMAC_DECL(PRE, pre) \ + \ +OMAC_DECL(PRE, pre) \ + \ +typedef struct pre##_cmackey { \ + pre##_ctx ctx; /* Underlying cipher context */ \ + uint32 m0[PRE##_BLKSZ/4], m1[PRE##_BLKSZ/4]; /* Final block masks */ \ +} pre##_cmackey; \ + \ +typedef struct pre##_cmacctx { \ + pre##_cmackey k; /* Processed key material */ \ + uint32 a[PRE##_BLKSZ/4]; /* Chaining state */ \ + octet b[PRE##_BLKSZ]; /* Input buffer */ \ + unsigned off; /* Offset into buffered data */ \ +} pre##_cmacctx; \ + \ +/* --- @pre_cmacsetkey@ --- * \ + * \ + * Arguments: @pre_cmackey *key@ = pointer to CMAC key block \ + * @ocnst void *k@ = pointer to key material \ + * @size_t ksz@ = size of key material \ + * \ + * Returns: --- \ + * \ + * Use: Initializes a CMAC key. This can be used for several \ + * MAC operations. \ + */ \ + \ +extern void pre##_cmacsetkey(pre##_cmackey */*key*/, \ + const void */*k*/, size_t /*ksz*/); \ + \ +/* --- @pre##_cmacinit@ --- * \ + * \ + * Arguments: @pre_cmacctx *ctx@ = pointer to context block \ + * @pre_cmackey *k@ = key block \ + * \ + * Returns: --- \ + * \ + * Use: Initializes a CMAC context ready to process a message. \ + * It's not necessary to keep the key around. \ + */ \ + \ +extern void pre##_cmacinit(pre##_cmacctx */*ctx*/, \ + const pre##_cmackey */*k*/); \ + \ +/* --- @pre_cmachash@ --- * \ + * \ + * Arguments: @pre_cmacctx *ctx@ = pointer to CMAC context block \ + * @ocnst void *p@ = pointer to message buffer \ + * @size_t sz@ = size of message buffer \ + * \ + * Returns: --- \ + * \ + * Use: Hashes some input data. \ + */ \ + \ +extern void pre##_cmachash(pre##_cmacctx */*ctx*/, \ + const void */*p*/, size_t /*sz*/); \ + \ +/* --- @pre_cmacdone@ --- * \ + * \ + * Arguments: @pre_cmacctx *ctx@ = pointer to CMAC context block \ + * @void *t@ = where to write the tag \ + * \ + * Returns: --- \ + * \ + * Use: Finishes a MAC operation and produces the tag. \ + */ \ + \ +extern void pre##_cmacdone(pre##_cmacctx */*ctx*/, void */*t*/); \ + \ +/* --- Generic MAC interface --- */ \ + \ +extern const gcmac pre##_cmac; + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/counter-def.h b/symm/counter-def.h index ad955dba..3c949c7a 100644 --- a/symm/counter-def.h +++ b/symm/counter-def.h @@ -56,6 +56,10 @@ # include "paranoia.h" #endif +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + /*----- Macros ------------------------------------------------------------*/ /* --- @COUNTER_DEF@ --- * @@ -84,9 +88,7 @@ */ \ \ void pre##_countergetiv(const pre##_counterctx *ctx, void *iv) \ -{ \ - BLKC_STORE(PRE, iv, ctx->n); \ -} \ + { BLKC_STORE(PRE, iv, ctx->c); } \ \ /* --- @pre_countersetiv@ --- * \ * \ @@ -99,10 +101,7 @@ void pre##_countergetiv(const pre##_counterctx *ctx, void *iv) \ */ \ \ void pre##_countersetiv(pre##_counterctx *ctx, const void *iv) \ -{ \ - BLKC_LOAD(PRE, ctx->n, iv); \ - ctx->off = PRE##_BLKSZ; \ -} \ + { BLKC_LOAD(PRE, ctx->c, iv); ctx->off = PRE##_BLKSZ; } \ \ /* --- @pre_counterbdry@ --- * \ * \ @@ -115,10 +114,7 @@ void pre##_countersetiv(pre##_counterctx *ctx, const void *iv) \ */ \ \ void pre##_counterbdry(pre##_counterctx *ctx) \ -{ \ - BLKC_STEP(PRE, ctx->n); \ - ctx->off = PRE##_BLKSZ; \ -} \ + { BLKC_STEP(PRE, ctx->c); ctx->off = PRE##_BLKSZ; } \ \ /* --- @pre_countersetkey@ --- * \ * \ @@ -131,9 +127,7 @@ void pre##_counterbdry(pre##_counterctx *ctx) \ */ \ \ void pre##_countersetkey(pre##_counterctx *ctx, const pre##_ctx *k) \ -{ \ - ctx->ctx = *k; \ -} \ + { ctx->ctx = *k; } \ \ /* --- @pre_counterinit@ --- * \ * \ @@ -156,6 +150,7 @@ void pre##_counterinit(pre##_counterctx *ctx, \ const void *iv) \ { \ static const octet zero[PRE##_BLKSZ] = { 0 }; \ + \ pre##_init(&ctx->ctx, key, sz); \ pre##_countersetiv(ctx, iv ? iv : zero); \ } \ @@ -176,81 +171,66 @@ void pre##_counterinit(pre##_counterctx *ctx, \ * use the cipher as a random data generator. \ */ \ \ +static const rsvr_policy pre##_counterpolicy = \ + { 0, PRE##_BLKSZ, PRE##_BLKSZ }; \ + \ void pre##_counterencrypt(pre##_counterctx *ctx, \ const void *src, void *dest, \ size_t sz) \ { \ - const octet *s = src; \ + rsvr_plan plan; \ + const octet *s = src, *p; \ octet *d = dest; \ - unsigned off = ctx->off; \ - \ - /* --- Empty blocks are trivial --- */ \ - \ - if (!sz) \ - return; \ - \ - /* --- If I can deal with the block from my buffer, do that --- */ \ - \ - if (sz < PRE##_BLKSZ - off) \ - goto small; \ - \ - /* --- Finish off what's left in my buffer --- */ \ - \ - if (!d) \ - sz -= PRE##_BLKSZ - off; \ - else { \ - while (off < PRE##_BLKSZ) { \ - register octet x = s ? *s++ : 0; \ - *d++ = ctx->buf[off++] ^ x; \ - sz--; \ + uint32 t[PRE##_BLKSZ/4]; \ + \ + /* Construct a plan and prepare to follow through. */ \ + rsvr_mkplan(&plan, &pre##_counterpolicy, ctx->off, sz); \ + \ + /* Initial portion, fulfilled from the buffer. If the chunk is small \ + * enough, then this will be the only portion. If the buffer is \ + * currently empty, then we must prepare it. \ + */ \ + if (plan.head) { \ + if (!ctx->off) { \ + pre##_eblk(&ctx->ctx, ctx->c, t); BLKC_STEP(PRE, ctx->c); \ + BLKC_STORE(PRE, ctx->b, t); \ } \ + p = ctx->b + ctx->off; ctx->off += plan.head; \ + if (!d) /* nothing to do */; \ + else if (!s) { memcpy(d, p, plan.head); d += plan.head; } \ + else while (plan.head--) *d++ = *s++ ^ *p++; \ } \ \ - /* --- Main encryption loop --- */ \ - \ - { \ - uint32 n[PRE##_BLKSZ / 4]; \ - \ - for (;;) { \ - pre##_eblk(&ctx->ctx, ctx->n, n); \ - BLKC_STEP(PRE, ctx->n); \ - if (sz < PRE##_BLKSZ) \ - break; \ - if (d) { \ - if (!s) \ - BLKC_STORE(PRE, d, n); \ - else { \ - uint32 x[PRE##_BLKSZ / 4]; \ - BLKC_LOAD(PRE, x, s); \ - BLKC_XSTORE(PRE, d, n, x); \ - s += PRE##_BLKSZ; \ - } \ - d += PRE##_BLKSZ; \ - } \ - sz -= PRE##_BLKSZ; \ - } \ + /* If the buffer is all used, then reset it ready for next time. */ \ + ctx->off -= plan.from_rsvr; \ \ - BLKC_STORE(PRE, ctx->buf, n); \ - off = 0; \ + /* Handle multiple whole blocks. */ \ + if (!d) \ + BLKC_ADD(PRE, ctx->c, plan.from_input/PRE##_BLKSZ); \ + else if (!s) while (plan.from_input) { \ + pre##_eblk(&ctx->ctx, ctx->c, t); BLKC_STEP(PRE, ctx->c); \ + BLKC_STORE(PRE, d, t); d += PRE##_BLKSZ; \ + plan.from_input -= PRE##_BLKSZ; \ + } else while (plan.from_input) { \ + pre##_eblk(&ctx->ctx, ctx->c, t); BLKC_STEP(PRE, ctx->c); \ + BLKC_XLOAD(PRE, t, s); s += PRE##_BLKSZ; \ + BLKC_STORE(PRE, d, t); d += PRE##_BLKSZ; \ + plan.from_input -= PRE##_BLKSZ; \ } \ \ - /* --- Tidying up the tail end --- */ \ - \ - if (sz) { \ - small: \ - if (!d) \ - off += sz; \ - else do { \ - register octet x = s ? *s++ : 0; \ - *d++ = ctx->buf[off++] ^ x; \ - sz--; \ - } while (sz); \ + /* Final portion. Note that the buffer must be empty if there is a \ + * tail, since otherwise the input data would have been part of the \ + * head portion instad. */ \ + if (!plan.tail) \ + BLKC_STORE(PRE, ctx->b, t); \ + else { \ + pre##_eblk(&ctx->ctx, ctx->c, t); BLKC_STEP(PRE, ctx->c); \ + BLKC_STORE(PRE, ctx->b, t); \ + p = ctx->b; ctx->off += plan.tail; \ + if (!d) /* nothing to do */; \ + else if (!s) { memcpy(d, p, plan.tail); d += plan.tail; } \ + else while (plan.tail--) *d++ = *s++ ^ *p++; \ } \ - \ - /* --- Done --- */ \ - \ - ctx->off = off; \ - return; \ } \ \ /* --- Generic cipher interface --- */ \ @@ -271,29 +251,16 @@ static gcipher *ginit(const void *k, size_t sz) \ } \ \ static void gencrypt(gcipher *c, const void *s, void *t, size_t sz) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_counterencrypt(&g->k, s, t, sz); \ -} \ + { gctx *g = (gctx *)c; pre##_counterencrypt(&g->k, s, t, sz); } \ \ static void gdestroy(gcipher *c) \ -{ \ - gctx *g = (gctx *)c; \ - BURN(*g); \ - S_DESTROY(g); \ -} \ + { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); } \ \ static void gsetiv(gcipher *c, const void *iv) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_countersetiv(&g->k, iv); \ -} \ + { gctx *g = (gctx *)c; pre##_countersetiv(&g->k, iv); } \ \ static void gbdry(gcipher *c) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_counterbdry(&g->k); \ -} \ + { gctx *g = (gctx *)c; pre##_counterbdry(&g->k); } \ \ static const gcipher_ops gops = { \ &pre##_counter, \ @@ -343,11 +310,11 @@ static int grmisc(grand *r, unsigned op, ...) \ } \ break; \ case GRAND_SEEDINT: \ - BLKC_SET(PRE, g->k.n, va_arg(ap, unsigned)); \ + BLKC_SET(PRE, g->k.c, va_arg(ap, unsigned)); \ g->k.off = PRE##_BLKSZ; \ break; \ case GRAND_SEEDUINT32: \ - BLKC_SET(PRE, g->k.n, va_arg(ap, uint32)); \ + BLKC_SET(PRE, g->k.c, va_arg(ap, uint32)); \ g->k.off = PRE##_BLKSZ; \ break; \ case GRAND_SEEDBLOCK: { \ @@ -391,10 +358,7 @@ static uint32 grword(grand *r) \ } \ \ static void grfill(grand *r, void *p, size_t sz) \ -{ \ - grctx *g = (grctx *)r; \ - pre##_counterencrypt(&g->k, 0, p, sz); \ -} \ + { grctx *g = (grctx *)r; pre##_counterencrypt(&g->k, 0, p, sz); } \ \ static const grand_ops grops = { \ name "-counter", \ @@ -430,9 +394,7 @@ COUNTER_TESTX(PRE, pre, name, fname) #ifdef TEST_RIG -#include - -#include "daftstory.h" +#include "modes-test.h" /* --- @COUNTER_TEST@ --- * * @@ -443,85 +405,24 @@ COUNTER_TESTX(PRE, pre, name, fname) #define COUNTER_TESTX(PRE, pre, name, fname) \ \ -/* --- Initial plaintext for the test --- */ \ - \ -static const octet text[] = TEXT; \ - \ -/* --- Key and IV to use --- */ \ - \ -static const octet key[] = KEY; \ -static const octet iv[] = IV; \ +static pre##_ctx key; \ +static pre##_counterctx ctx; \ \ -/* --- Buffers for encryption and decryption output --- */ \ +static void pre##_counter_test_setup(const octet *k, size_t ksz) \ + { pre##_init(&key, k, ksz); pre##_countersetkey(&ctx, &key); } \ \ -static octet ct[sizeof(text)]; \ -static octet pt[sizeof(text)]; \ +static void pre##_counter_test_reset(const octet *iv) \ + { pre##_countersetiv(&ctx, iv); } \ \ -static void hexdump(const octet *p, size_t sz, size_t off) \ -{ \ - const octet *q = p + sz; \ - for (sz = 0; p < q; p++, sz++) { \ - printf("%02x", *p); \ - if ((off + sz + 1) % PRE##_BLKSZ == 0) \ - putchar(':'); \ - } \ -} \ +static void pre##_counter_test_enc(const octet *s, octet *d, size_t sz) \ + { pre##_counterencrypt(&ctx, s, d, sz); } \ \ -int main(void) \ +int main(int argc, char *argv[]) \ { \ - size_t sz = 0, rest; \ - pre##_counterctx ctx; \ - int status = 0; \ - int done = 0; \ - pre##_ctx k; \ - \ - size_t keysz = PRE##_KEYSZ ? \ - PRE##_KEYSZ : strlen((const char *)key); \ - \ - fputs(name "-counter: ", stdout); \ - \ - pre##_init(&k, key, keysz); \ - pre##_countersetkey(&ctx, &k); \ - \ - while (sz <= sizeof(text)) { \ - rest = sizeof(text) - sz; \ - memcpy(ct, text, sizeof(text)); \ - pre##_countersetiv(&ctx, iv); \ - pre##_counterencrypt(&ctx, ct, ct, sz); \ - pre##_counterencrypt(&ctx, ct + sz, ct + sz, rest); \ - memcpy(pt, ct, sizeof(text)); \ - pre##_countersetiv(&ctx, iv); \ - pre##_counterencrypt(&ctx, pt, pt, rest); \ - pre##_counterencrypt(&ctx, pt + rest, pt + rest, sz); \ - if (memcmp(pt, text, sizeof(text)) == 0) { \ - done++; \ - if (sizeof(text) < 40 || done % 8 == 0) \ - fputc('.', stdout); \ - if (done % 480 == 0) \ - fputs("\n\t", stdout); \ - fflush(stdout); \ - } else { \ - printf("\nError (sz = %lu)\n", (unsigned long)sz); \ - status = 1; \ - printf("\tplaintext = "); hexdump(text, sz, 0); \ - printf(", "); hexdump(text + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\tciphertext = "); hexdump(ct, sz, 0); \ - printf(", "); hexdump(ct + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\trecovered text = "); hexdump(pt, sz, 0); \ - printf(", "); hexdump(pt + sz, rest, sz); \ - fputc('\n', stdout); \ - fputc('\n', stdout); \ - } \ - if (sz < 63) \ - sz++; \ - else \ - sz += 9; \ - } \ - \ - fputs(status ? " failed\n" : " ok\n", stdout); \ - return (status); \ + return test_encmode(fname "-counter", PRE##_KEYSZ, PRE##_BLKSZ, 1, 0, \ + pre##_counter_test_setup, pre##_counter_test_reset, \ + pre##_counter_test_enc, pre##_counter_test_enc, \ + argc, argv); \ } #else diff --git a/symm/counter.h b/symm/counter.h index 7e07b3c5..418f1489 100644 --- a/symm/counter.h +++ b/symm/counter.h @@ -62,8 +62,8 @@ typedef struct pre##_counterctx { \ pre##_ctx ctx; /* Underlying cipher context */ \ unsigned off; /* Current offset in buffer */ \ - octet buf[PRE##_BLKSZ]; /* Output buffer */ \ - uint32 n[PRE##_BLKSZ / 4]; /* Counter */ \ + octet b[PRE##_BLKSZ]; /* Output buffer */ \ + uint32 c[PRE##_BLKSZ / 4]; /* Counter */ \ } pre##_counterctx; \ \ /* --- @pre_countergetiv@ --- * \ diff --git a/symm/daftstory.h b/symm/daftstory.h deleted file mode 100644 index b4d6b58c..00000000 --- a/symm/daftstory.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -*-c-*- - * - * Daft story for use in test encryptions - * - * (c) 1999 Straylight/Edgeware - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of Catacomb. - * - * Catacomb is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * Catacomb is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with Catacomb; if not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef CATACOMB_DAFTSTORY_H -#define CATACOMB_DAFTSTORY_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Macros ------------------------------------------------------------*/ - -/* --- Don't ask --- */ - -#ifdef SMALL_TEST -# define TEXT "A small piece of text for testing encryption." -#else -# define STORY "\ -Once upon a time there were a beautiful princess, a slightly nutty wizard,\n\ -and a watermelon. Now, the watermelon had decided that it probably wasn't\n\ -going to get very far with the princess unless it did something pretty\n\ -drastic. So it asked the wizard to turn it into a handsome prince.\n\ -\n\ -At least, this is the way that the wizard viewed the situation. He might\n\ -have just hallucinated it all; those mushrooms had looked ever so nice.\n\ -\n\ -Back to the point. The watermelon had expressed its desire not to be a\n\ -watermelon any more. And the wizard was probably tripping something quite\n\ -powerful. He hunted around a bit for his staff, and mumbled something\n\ -that film directors would think of as sounding appropriately arcane and\n\ -mystical (but was, in fact, just the ingredients list for an ancient\n\ -remedy for athlete's foot) and *pop*. Cooked watermelon. Yuk.\n\ -\n\ -Later in the year, the princess tripped over the hem of her dress, fell\n\ -down a spiral staircase, and died. The king ordered dressmakers to attach\n\ -safety warnings to long dresses.\n\ -\n\ -And the wizard? Who cares?\n\ -" -# define TEXT STORY STORY -#endif - -#define KEY "Penguins rule OK, rhubarb cauliflower" -#define IV "EdgewareCatacomb, parsley, sage, rosemary and thyme" - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/symm/eax-def.h b/symm/eax-def.h new file mode 100644 index 00000000..6e1c7ca4 --- /dev/null +++ b/symm/eax-def.h @@ -0,0 +1,850 @@ +/* -*-c-*- + * + * The EAX authenticated-encryption mode + * + * (c) 2017 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef CATACOMB_EAX_DEF_H +#define CATACOMB_EAX_DEF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +#ifndef CATACOMB_ARENA_H +# include "arena.h" +#endif + +#ifndef CATACOMB_BLKC_H +# include "blkc.h" +#endif + +#ifndef CATACOMB_CT_H +# include "ct.h" +#endif + +#ifndef CATACOMB_CMAC_H +# include "cmac.h" +#endif + +#ifndef CATACOMB_CMAC_DEF_H +# include "cmac-def.h" +#endif + +#ifndef CATACOMB_KEYSZ_H +# include "keysz.h" +#endif + +#ifndef CATACOMB_PARANOIA_H +# include "paranoia.h" +#endif + +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @EAX_DEF@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates an implementation for the EAX authenticated- + * encryption mode. + */ + +#define EAX_DEF(PRE, pre) EAX_DEFX(PRE, pre, #pre, #pre) + +#define EAX_DEFX(PRE, pre, name, fname) \ + \ +OMAC_DECL(PRE, pre) \ + \ +const octet \ + pre##_eaxnoncesz[] = { KSZ_ANY, PRE##_BLKSZ }, \ + pre##_eaxtagsz[] = { KSZ_RANGE, PRE##_BLKSZ, 0, PRE##_BLKSZ, 1 }; \ + \ +/* --- @pre_eaxsetkey@ --- * \ + * \ + * Arguments: @pre_eaxkey *key@ = pointer to key block to fill in \ + * @const void *k@ = pointer to key material \ + * @size_t ksz@ = size of key material \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an EAX key block. \ + */ \ + \ +void pre##_eaxsetkey(pre##_eaxkey *key, const void *k, size_t ksz) \ +{ \ + uint32 t[PRE##_BLKSZ/4]; \ + \ + /* Initialize the block cipher. */ \ + pre##_init(&key->ctx, k, ksz); \ + \ + /* Set up the OMAC masks. */ \ + pre##_omacmasks(&key->ctx, key->m0, key->m1); \ + \ + /* Set up the OMAC tweaks. EAX tweaks its MAC by simply stitching \ + * magic block-wide prefixes %$t_0$%, %$t_1$%, %$t_2$% (which are \ + * simply the numbers 0, 1, 2) on the front of strings. We can \ + * accelerate things by caching two values for each tweak: \ + * \ + * * %$v_i = E_K(t_i)$% is the accumulator that results from \ + * pushing the tweak through the blockcipher, which we'd \ + * calculate if the original message was nonempty. \ + * \ + * * %$z_i = E_K(t_0 \xor m_0)$% is the tweak with the `full final \ + * buffer' mask applied, which is the final tag for a final empty \ + * message. \ + */ \ + BLKC_BSET(PRE, t, 0); pre##_eblk(&key->ctx, t, key->v0); \ + BLKC_XMOVE(PRE, t, key->m0); pre##_eblk(&key->ctx, t, key->z0); \ + BLKC_BSET(PRE, t, 1); pre##_eblk(&key->ctx, t, key->v1); \ + BLKC_XMOVE(PRE, t, key->m0); pre##_eblk(&key->ctx, t, key->z1); \ + BLKC_BSET(PRE, t, 2); pre##_eblk(&key->ctx, t, key->v2); \ + BLKC_XMOVE(PRE, t, key->m0); pre##_eblk(&key->ctx, t, key->z2); \ +} \ + \ +/* --- @pre_eaxaadinit@ --- * \ + * \ + * Arguments: @pre_eaxaadctx *aad@ = pointer to AAD context \ + * @const pre_eaxkey *key@ = pointer to key block \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an EAX AAD (`additional authenticated \ + * data') context associated with a given key. AAD \ + * contexts can be copied and/or reused, saving time if \ + * the AAD for a number of messages has a common prefix. \ + * \ + * The @key@ doesn't need to be kept around, though \ + * usually there'll at least be another copy in some EAX \ + * operation context because the AAD on its own isn't much \ + * good. \ + */ \ + \ +void pre##_eaxaadinit(pre##_eaxaadctx *aad, const pre##_eaxkey *key) \ + { aad->k = *key; aad->off = 0; BLKC_MOVE(PRE, aad->a, key->v1); } \ + \ +/* --- @pre_eaxaadhash@ --- * \ + * \ + * Arguments: @pre_eaxaadctx *aad@ = pointer to AAD context \ + * @const void *p@ = pointer to AAD material \ + * @size_t sz@ = length of AAD material \ + * \ + * Returns: --- \ + * \ + * Use: Feeds AAD into the context. \ + */ \ + \ +void pre##_eaxaadhash(pre##_eaxaadctx *aad, const void *p, size_t sz) \ +{ \ + rsvr_state st; \ + const octet *q; \ + \ + rsvr_setup(&st, &pre##_omacpolicy, aad->b, &aad->off, p, sz); \ + RSVR_DO(&st) while ((q = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) \ + OMAC_BLOCK(PRE, pre, &aad->k.ctx, aad->a, q); \ +} \ + \ +/* --- @pre_eaxinit@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to EAX context \ + * @const pre_eaxkey *key@ = pointer to key block \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: --- \ + * \ + * Use: Initialize an EAX operation context with a given key. \ + * \ + * The original key needn't be kept around any more. \ + */ \ + \ +void pre##_eaxinit(pre##_eaxctx *ctx, const pre##_eaxkey *k, \ + const void *n, size_t nsz) \ + { ctx->k = *k; pre##_eaxreinit(ctx, n, nsz); } \ + \ +/* --- @pre_eaxreinit@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to EAX context \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: --- \ + * \ + * Use: Reinitialize an EAX operation context, changing the \ + * nonce. \ + */ \ + \ +void pre##_eaxreinit(pre##_eaxctx *ctx, const void *n, size_t nsz) \ +{ \ + octet b[PRE##_BLKSZ]; \ + const octet *q = n; \ + \ + /* Initialize the OMAC context with the right tweak. */ \ + BLKC_MOVE(PRE, ctx->a, ctx->k.v2); \ + ctx->off = 0; \ + \ + /* Calculate the initial counter from the nonce. This is OMAC again, \ + * but this time we know that we're starting from a clean slate and \ + * we have the whole input in one go, so we don't bother with the \ + * full reservoir machinery. \ + */ \ + if (!nsz) \ + BLKC_MOVE(PRE, ctx->c0, ctx->k.z0); \ + else { \ + BLKC_MOVE(PRE, ctx->c0, ctx->k.v0); \ + while (nsz > PRE##_BLKSZ) { \ + OMAC_BLOCK(PRE, pre, &ctx->k.ctx, ctx->c0, q); \ + q += PRE##_BLKSZ; nsz -= PRE##_BLKSZ; \ + } \ + memcpy(b, q, nsz); \ + pre##_omacdone(&ctx->k.ctx, ctx->k.m0, ctx->k.m1, \ + ctx->c0, b, nsz); \ + } \ + \ + /* We must remember the initial counter for the final tag \ + * calculation. (I conjecture that storing the final counter instead \ + * would be just as secure, and require less state, but I've not \ + * proven this, and anyway it wouldn't interoperate.) Copy it to \ + * make the working counter. \ + */ \ + BLKC_MOVE(PRE, ctx->c, ctx->c0); \ +} \ + \ +/* --- @pre_eaxencrypt@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to EAX operation context \ + * @const void *src@ = pointer to plaintext message chunk \ + * @size_t sz@ = size of the plaintext \ + * @buf *dst@ = a buffer to write the ciphertext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Encrypts a chunk of a plaintext message, writing a \ + * chunk of ciphertext to the output buffer and updating \ + * the operation state. \ + * \ + * For EAX, we always write a ciphertext chunk the same \ + * size as the plaintext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +int pre##_eaxencrypt(pre##_eaxctx *ctx, \ + const void *src, size_t sz, buf *dst) \ +{ \ + rsvr_plan plan; \ + uint32 t[PRE##_BLKSZ/4]; \ + const octet *p = src; \ + octet *q, *r, y; \ + \ + /* Allocate space for the ciphertext. */ \ + if (sz) { q = buf_get(dst, sz); if (!q) return (-1); } \ + else q = 0; \ + \ + /* Determine the buffering plan. Our buffer is going to do double- \ + * duty here. The end portion is going to contain mask from the \ + * encrypted counter which we mix into the plaintext to encrypt it; \ + * the start portion, which originally mask bytes we've already used, \ + * will hold the output ciphertext, which will eventually be \ + * collected into the OMAC state. \ + */ \ + rsvr_mkplan(&plan, &pre##_omacpolicy, ctx->off, sz); \ + \ + /* Initial portion, fulfilled from the buffer. If the buffer is \ + * empty, then that means that we haven't yet encrypted the current \ + * counter, so we should do that and advance it. \ + */ \ + if (plan.head) { \ + if (!ctx->off) { \ + pre##_eblk(&ctx->k.ctx, ctx->c, t); BLKC_BSTEP(PRE, ctx->c); \ + BLKC_STORE(PRE, ctx->b, t); \ + } \ + r = ctx->b + ctx->off; ctx->off += plan.head; \ + while (plan.head--) { y = *p++ ^ *r; *r++ = *q++ = y; } \ + } \ + \ + /* If we've filled up the buffer then we need to cycle the MAC and \ + * reset the offset. \ + */ \ + if (plan.from_rsvr) { \ + OMAC_BLOCK(PRE, pre, &ctx->k.ctx, ctx->a, ctx->b); \ + ctx->off = 0; \ + } \ + \ + /* Now to process the main body of the input. We sneakily open-code \ + * the OMAC part of this. \ + */ \ + while (plan.from_input) { \ + pre##_eblk(&ctx->k.ctx, ctx->c, t); BLKC_BSTEP(PRE, ctx->c); \ + BLKC_XLOAD(PRE, t, p); p += PRE##_BLKSZ; \ + BLKC_STORE(PRE, q, t); q += PRE##_BLKSZ; \ + BLKC_XMOVE(PRE, ctx->a, t); pre##_eblk(&ctx->k.ctx, ctx->a, ctx->a); \ + plan.from_input -= PRE##_BLKSZ; \ + } \ + \ + /* Finally, deal with any final portion. If there is one, we know \ + * that the buffer is empty: we must have filled it above, or this \ + * would all count as `initial' data. \ + */ \ + if (plan.tail) { \ + pre##_eblk(&ctx->k.ctx, ctx->c, t); BLKC_BSTEP(PRE, ctx->c); \ + BLKC_STORE(PRE, ctx->b, t); \ + r = ctx->b; ctx->off += plan.tail; \ + while (plan.tail--) { y = *p++ ^ *r; *r++ = *q++ = y; } \ + } \ + \ + /* And we're done. */ \ + return (0); \ +} \ + \ +/* --- @pre_eaxdecrypt@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to EAX operation context \ + * @const void *src@ = pointer to ciphertext message chunk \ + * @size_t sz@ = size of the ciphertext \ + * @buf *dst@ = a buffer to write the plaintext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Decrypts a chunk of a ciphertext message, writing a \ + * chunk of plaintext to the output buffer and updating \ + * the operation state. \ + * \ + * For EAX, we always write a plaintext chunk the same \ + * size as the ciphertext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +int pre##_eaxdecrypt(pre##_eaxctx *ctx, \ + const void *src, size_t sz, buf *dst) \ +{ \ + rsvr_plan plan; \ + uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ]; \ + const octet *p = src; \ + octet *q, *r, y; \ + \ + /* Allocate space for the plaintext. */ \ + if (sz) { q = buf_get(dst, sz); if (!q) return (-1); } \ + else q = 0; \ + \ + /* Determine the buffering plan. Our buffer is going to do double- \ + * duty here. The end portion is going to contain mask from the \ + * encrypted counter which we mix into the plaintext to encrypt it; \ + * the start portion, which originally mask bytes we've already used, \ + * will hold the input ciphertext, which will eventually be \ + * collected into the OMAC state. \ + */ \ + rsvr_mkplan(&plan, &pre##_omacpolicy, ctx->off, sz); \ + \ + /* Initial portion, fulfilled from the buffer. If the buffer is \ + * empty, then that means that we haven't yet encrypted the current \ + * counter, so we should do that and advance it. \ + */ \ + if (plan.head) { \ + if (!ctx->off) { \ + pre##_eblk(&ctx->k.ctx, ctx->c, t); BLKC_BSTEP(PRE, ctx->c); \ + BLKC_STORE(PRE, ctx->b, t); \ + } \ + r = ctx->b + ctx->off; ctx->off += plan.head; \ + while (plan.head--) { y = *p++; *q++ = y ^ *r; *r++ = y; } \ + } \ + \ + /* If we've filled up the buffer then we need to cycle the MAC and \ + * reset the offset. \ + */ \ + if (plan.from_rsvr) { \ + OMAC_BLOCK(PRE, pre, &ctx->k.ctx, ctx->a, ctx->b); \ + ctx->off = 0; \ + } \ + \ + /* Now to process the main body of the input. We sneakily open-code \ + * the OMAC part of this. \ + */ \ + while (plan.from_input) { \ + pre##_eblk(&ctx->k.ctx, ctx->c, t); BLKC_BSTEP(PRE, ctx->c); \ + BLKC_LOAD(PRE, u, p); p += PRE##_BLKSZ; \ + BLKC_XSTORE(PRE, q, t, u); q += PRE##_BLKSZ; \ + BLKC_XMOVE(PRE, ctx->a, u); pre##_eblk(&ctx->k.ctx, ctx->a, ctx->a); \ + plan.from_input -= PRE##_BLKSZ; \ + } \ + \ + /* Finally, deal with any final portion. If there is one, we know \ + * that the buffer is empty: we must have filled it above, or this \ + * would all count as `initial' data. \ + */ \ + if (plan.tail) { \ + pre##_eblk(&ctx->k.ctx, ctx->c, t); BLKC_BSTEP(PRE, ctx->c); \ + BLKC_STORE(PRE, ctx->b, t); \ + r = ctx->b; ctx->off += plan.tail; \ + while (plan.tail--) { y = *p++; *q++ = y ^ *r; *r++ = y; } \ + } \ + \ + /* And we're done. */ \ + return (0); \ +} \ + \ +/* --- @pre_eaxtag@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to an EAX context \ + * @const pre_eaxaadctx *aad@ = pointer to AAD context, or \ + * null \ + * @octet *t@ = where to write a (full-length) tag \ + * \ + * Returns: --- \ + * \ + * Use: Finishes an EAX operation, by calculating the tag. \ + */ \ + \ +static void pre##_eaxtag(pre##_eaxctx *ctx, \ + const pre##_eaxaadctx *aad, octet *t) \ +{ \ + octet b[PRE##_BLKSZ]; \ + uint32 u[PRE##_BLKSZ/4]; \ + \ + /* Finish tagging the ciphertext. (The buffer is empty if and only \ + * if there was no message, since the OMAC reservoir policy leaves \ + * the buffer full.) \ + */ \ + if (!ctx->off) BLKC_MOVE(PRE, ctx->a, ctx->k.z2); \ + else pre##_omacdone(&ctx->k.ctx, ctx->k.m0, ctx->k.m1, \ + ctx->a, ctx->b, ctx->off); \ + \ + /* If there's no AAD, because the pointer is null or no data was \ + * supplied, then use the cached empty-header tag. Otherwise \ + * calculate the tag for the AAD. Either way, mix the result into \ + * ctx->A, and be careful not to modify the AAD context. (Again, the \ + * buffer is empty if and only if there was no AAD.) \ + */ \ + if (!aad || !aad->off) BLKC_XMOVE(PRE, ctx->a, ctx->k.z1); \ + else { \ + BLKC_MOVE(PRE, u, aad->a); memcpy(b, aad->b, aad->off); \ + pre##_omacdone(&ctx->k.ctx, ctx->k.m0, ctx->k.m1, u, b, aad->off); \ + BLKC_XMOVE(PRE, ctx->a, u); \ + } \ + \ + /* Finally, mix in the initial counter value. */ \ + BLKC_XMOVE(PRE, ctx->a, ctx->c0); \ + \ + /* We're done. */ \ + BLKC_STORE(PRE, t, ctx->a); \ +} \ + \ +/* --- @pre_eaxencryptdone@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to an EAX context \ + * @const pre_eaxaadctx *aad@ = pointer to AAD context, or \ + * null \ + * @buf *dst@ = buffer for remaining ciphertext \ + * @void *tag@ = where to write the tag \ + * @size_t tsz@ = length of tag to store \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Completes an EAX encryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. EAX doesn't buffer ciphertext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +int pre##_eaxencryptdone(pre##_eaxctx *ctx, \ + const pre##_eaxaadctx *aad, buf *dst, \ + void *tag, size_t tsz) \ +{ \ + octet t[PRE##_BLKSZ]; \ + \ + if (tsz > PRE##_BLKSZ) return (-1); \ + if (!BOK(dst)) return (-1); \ + pre##_eaxtag(ctx, aad, t); memcpy(tag, t, tsz); \ + return (0); \ +} \ + \ +/* --- @pre_eaxdecryptdone@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to an EAX context \ + * @const pre_eaxaadctx *aad@ = pointer to AAD context, or \ + * null \ + * @buf *dst@ = buffer for remaining plaintext \ + * @const void *tag@ = tag to verify \ + * @size_t tsz@ = length of tag \ + * \ + * Returns: @+1@ for complete success; @0@ if tag verification \ + * failed; @-1@ for other kinds of errors. \ + * \ + * Use: Completes an EAX decryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. EAX doesn't buffer plaintext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +int pre##_eaxdecryptdone(pre##_eaxctx *ctx, \ + const pre##_eaxaadctx *aad, buf *dst, \ + const void *tag, size_t tsz) \ +{ \ + octet t[PRE##_BLKSZ]; \ + \ + if (tsz > PRE##_BLKSZ) return (-1); \ + if (!BOK(dst)) return (-1); \ + pre##_eaxtag(ctx, aad, t); \ + if (!ct_memeq(tag, t, tsz)) return (0); \ + else return (+1); \ +} \ + \ +/* --- Generic AEAD interface --- */ \ + \ +typedef struct gactx { \ + gaead_aad a; \ + pre##_eaxaadctx aad; \ +} gactx; \ + \ + \ +static gaead_aad *gadup(const gaead_aad *a) \ + { gactx *aad = S_CREATE(gactx); *aad = *(gactx *)a; return (&aad->a); } \ + \ +static void gahash(gaead_aad *a, const void *h, size_t hsz) \ + { gactx *aad = (gactx *)a; pre##_eaxaadhash(&aad->aad, h, hsz); } \ + \ +static void gadestroy(gaead_aad *a) \ + { gactx *aad = (gactx *)a; BURN(*aad); S_DESTROY(aad); } \ + \ +static const gaead_aadops gaops = \ + { &pre##_eax, gadup, gahash, gadestroy }; \ + \ +static gaead_aad *gaad(const pre##_eaxkey *k) \ +{ \ + gactx *aad = S_CREATE(gactx); \ + aad->a.ops = &gaops; \ + pre##_eaxaadinit(&aad->aad, k); \ + return (&aad->a); \ +} \ + \ +typedef struct gectx { \ + gaead_enc e; \ + pre##_eaxctx ctx; \ +} gectx; \ + \ +static gaead_aad *geaad(gaead_enc *e) \ + { gectx *enc = (gectx *)e; return (gaad(&enc->ctx.k)); } \ + \ +static int gereinit(gaead_enc *e, const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gectx *enc = (gectx *)e; \ + \ + if (tsz > PRE##_BLKSZ) return (-1); \ + pre##_eaxreinit(&enc->ctx, n, nsz); \ + return (0); \ +} \ + \ +static int geenc(gaead_enc *e, const void *m, size_t msz, buf *b) \ +{ \ + gectx *enc = (gectx *)e; \ + return (pre##_eaxencrypt(&enc->ctx, m, msz, b)); \ +} \ + \ +static int gedone(gaead_enc *e, const gaead_aad *a, \ + buf *b, void *t, size_t tsz) \ +{ \ + gectx *enc = (gectx *)e; gactx *aad = (gactx *)a; \ + assert(!a || a->ops == &gaops); \ + return (pre##_eaxencryptdone(&enc->ctx, a ? &aad->aad : 0, b, t, tsz)); \ +} \ + \ +static void gedestroy(gaead_enc *e) \ + { gectx *enc = (gectx *)e; BURN(*enc); S_DESTROY(enc); } \ + \ +static const gaead_encops geops = \ + { &pre##_eax, geaad, gereinit, geenc, gedone, gedestroy }; \ + \ +typedef struct gdctx { \ + gaead_dec d; \ + pre##_eaxctx ctx; \ +} gdctx; \ + \ +static gaead_aad *gdaad(gaead_dec *d) \ + { gdctx *dec = (gdctx *)d; return (gaad(&dec->ctx.k)); } \ + \ +static int gdreinit(gaead_dec *d, const void *n, size_t nsz, \ + size_t hsz, size_t csz, size_t tsz) \ +{ \ + gdctx *dec = (gdctx *)d; \ + \ + if (tsz > PRE##_BLKSZ) return (-1); \ + pre##_eaxreinit(&dec->ctx, n, nsz); \ + return (0); \ +} \ + \ +static int gddec(gaead_dec *d, const void *c, size_t csz, buf *b) \ +{ \ + gdctx *dec = (gdctx *)d; \ + return (pre##_eaxdecrypt(&dec->ctx, c, csz, b)); \ +} \ + \ +static int gddone(gaead_dec *d, const gaead_aad *a, \ + buf *b, const void *t, size_t tsz) \ +{ \ + gdctx *dec = (gdctx *)d; gactx *aad = (gactx *)a; \ + assert(!a || a->ops == &gaops); \ + return (pre##_eaxdecryptdone(&dec->ctx, a ? &aad->aad : 0, b, t, tsz)); \ +} \ + \ +static void gddestroy(gaead_dec *d) \ + { gdctx *dec = (gdctx *)d; BURN(*dec); S_DESTROY(dec); } \ + \ +static const gaead_decops gdops = \ + { &pre##_eax, gdaad, gdreinit, gddec, gddone, gddestroy }; \ + \ +typedef struct gkctx { \ + gaead_key k; \ + pre##_eaxkey key; \ +} gkctx; \ + \ +static gaead_aad *gkaad(const gaead_key *k) \ + { gkctx *key = (gkctx *)k; return (gaad(&key->key)); } \ + \ +static gaead_enc *gkenc(const gaead_key *k, const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gkctx *key = (gkctx *)k; \ + gectx *enc; \ + \ + if (tsz > PRE##_BLKSZ) return (0); \ + enc = S_CREATE(gectx); enc->e.ops = &geops; \ + pre##_eaxinit(&enc->ctx, &key->key, n, nsz); \ + return (&enc->e); \ +} \ + \ +static gaead_dec *gkdec(const gaead_key *k, const void *n, size_t nsz, \ + size_t hsz, size_t csz, size_t tsz) \ +{ \ + gkctx *key = (gkctx *)k; \ + gdctx *dec; \ + \ + if (tsz > PRE##_BLKSZ) return (0); \ + dec = S_CREATE(gdctx); dec->d.ops = &gdops; \ + pre##_eaxinit(&dec->ctx, &key->key, n, nsz); \ + return (&dec->d); \ +} \ + \ +static void gkdestroy(gaead_key *k) \ + { gkctx *key = (gkctx *)k; BURN(*key); S_DESTROY(key); } \ + \ +static const gaead_keyops gkops = \ + { &pre##_eax, gkaad, gkenc, gkdec, gkdestroy }; \ + \ +static gaead_key *gckey(const void *k, size_t ksz) \ +{ \ + gkctx *key = S_CREATE(gkctx); \ + key->k.ops = &gkops; \ + pre##_eaxsetkey(&key->key, k, ksz); \ + return (&key->k); \ +} \ + \ +const gcaead pre##_eax = { \ + name "-eax", \ + pre##_keysz, pre##_eaxnoncesz, pre##_eaxtagsz, \ + PRE##_BLKSZ, 0, 0, 0, \ + gckey \ +}; \ + \ +EAX_TESTX(PRE, pre, name, fname) + +/*----- Test rig ----------------------------------------------------------*/ + +#define EAX_TEST(PRE, pre) EAX_TESTX(PRE, pre, #pre, #pre) + +/* --- @EAX_TEST@ --- * + * + * Arguments: @PRE, pre@ = prefixes for the underlying block cipher + * + * Use: Standard test rig for EAX functions. + */ + +#ifdef TEST_RIG + +#include + +#include +#include +#include + +#define EAX_TESTX(PRE, pre, name, fname) \ + \ +static int eaxverify(dstr *v) \ +{ \ + pre##_eaxkey key; \ + pre##_eaxaadctx aad; \ + pre##_eaxctx ctx; \ + int ok = 1, win; \ + int i; \ + octet *p; \ + int szs[] = { 1, 7, 192, -1, 0 }, *ip; \ + size_t hsz, msz; \ + dstr d = DSTR_INIT, t = DSTR_INIT; \ + buf b; \ + \ + dstr_ensure(&d, v[4].len > v[3].len ? v[4].len : v[3].len); \ + dstr_ensure(&t, v[5].len); t.len = v[5].len; \ + \ + pre##_eaxsetkey(&key, v[0].buf, v[0].len); \ + \ + for (ip = szs; *ip; ip++) { \ + \ + pre##_eaxinit(&ctx, &key, (octet *)v[1].buf, v[1].len); \ + \ + i = *ip; \ + hsz = v[2].len; \ + if (i == -1) i = hsz; \ + if (i > hsz) continue; \ + p = (octet *)v[2].buf; \ + pre##_eaxaadinit(&aad, &key); \ + while (hsz) { \ + if (i > hsz) i = hsz; \ + pre##_eaxaadhash(&aad, p, i); \ + p += i; hsz -= i; \ + } \ + \ + buf_init(&b, d.buf, d.sz); \ + i = *ip; \ + msz = v[3].len; \ + if (i == -1) i = msz; \ + if (i > msz) continue; \ + p = (octet *)v[3].buf; \ + while (msz) { \ + if (i > msz) i = msz; \ + if (pre##_eaxencrypt(&ctx, p, i, &b)) { \ + puts("!! eaxencrypt reports failure"); \ + goto fail_enc; \ + } \ + p += i; msz -= i; \ + } \ + \ + if (pre##_eaxencryptdone(&ctx, &aad, &b, (octet *)t.buf, t.len)) { \ + puts("!! eaxencryptdone reports failure"); \ + goto fail_enc; \ + } \ + d.len = BLEN(&b); \ + \ + if (d.len != v[4].len || \ + memcmp(d.buf, v[4].buf, v[4].len) != 0 || \ + memcmp(t.buf, v[5].buf, v[5].len) != 0) { \ + fail_enc: \ + printf("\nfail encrypt:\n\tstep = %i", *ip); \ + fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \ + fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \ + fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \ + fputs("\n\tmessage = ", stdout); type_hex.dump(&v[3], stdout); \ + fputs("\n\texp ct = ", stdout); type_hex.dump(&v[4], stdout); \ + fputs("\n\tcalc ct = ", stdout); type_hex.dump(&d, stdout); \ + fputs("\n\texp tag = ", stdout); type_hex.dump(&v[5], stdout); \ + fputs("\n\tcalc tag = ", stdout); type_hex.dump(&t, stdout); \ + putchar('\n'); \ + ok = 0; \ + } \ + \ + pre##_eaxinit(&ctx, &key, (octet *)v[1].buf, v[1].len); \ + \ + buf_init(&b, d.buf, d.sz); \ + i = *ip; \ + msz = v[4].len; \ + if (i == -1) i = msz; \ + if (i > msz) continue; \ + p = (octet *)v[4].buf; \ + while (msz) { \ + if (i > msz) i = msz; \ + if (pre##_eaxdecrypt(&ctx, p, i, &b)) { \ + puts("!! eaxdecrypt reports failure"); \ + win = 0; goto fail_dec; \ + } \ + p += i; msz -= i; \ + } \ + \ + win = pre##_eaxdecryptdone(&ctx, &aad, &b, \ + (octet *)v[5].buf, v[5].len); \ + if (win < 0) { \ + puts("!! eaxdecryptdone reports failure"); \ + goto fail_dec; \ + } \ + d.len = BLEN(&b); \ + \ + if (d.len != v[3].len || !win || \ + memcmp(d.buf, v[3].buf, v[3].len) != 0) { \ + fail_dec: \ + printf("\nfail decrypt:\n\tstep = %i", *ip); \ + fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \ + fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \ + fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \ + fputs("\n\tciphertext = ", stdout); type_hex.dump(&v[4], stdout); \ + fputs("\n\texp pt = ", stdout); type_hex.dump(&v[3], stdout); \ + fputs("\n\tcalc pt = ", stdout); type_hex.dump(&d, stdout); \ + fputs("\n\ttag = ", stdout); type_hex.dump(&v[5], stdout); \ + printf("\n\tverify %s", win ? "ok" : "FAILED"); \ + putchar('\n'); \ + ok = 0; \ + } \ + } \ + \ + dstr_destroy(&d); dstr_destroy(&t); \ + return (ok); \ +} \ + \ +static test_chunk aeaddefs[] = { \ + { name "-eax", eaxverify, \ + { &type_hex, &type_hex, &type_hex, &type_hex, \ + &type_hex, &type_hex, 0 } }, \ + { 0, 0, { 0 } } \ +}; \ + \ +int main(int argc, char *argv[]) \ +{ \ + ego(argv[0]); \ + test_run(argc, argv, aeaddefs, SRCDIR"/t/" fname); \ + return (0); \ +} + +#else +# define EAX_TESTX(PRE, pre, name, fname) +#endif + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/eax.h b/symm/eax.h new file mode 100644 index 00000000..0018da6d --- /dev/null +++ b/symm/eax.h @@ -0,0 +1,294 @@ +/* -*-c-*- + * + * The EAX authenticated-encryption mode + * + * (c) 2017 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Notes on EAX ------------------------------------------------------* + * + * The name doesn't appear to be short for anything convincing. EAX was + * designed in 2004 by Mihir Bellare, Phillip Rogaway, and David Wagner, as a + * response to CCM's deficiencies, which Rogaway and Wagner had complained + * about the previous year. Like CCM, it's a patent-free authenticated + * encryption scheme based on counter mode and CBC-MAC, and needs two + * blockcipher applications per message block, but it's much more refined + * than CCM. The EAX specification is clear about how the mode applies to + * arbitrary block sizes, and I've not had to make any decisions on how to + * extend it myself. + * + * EAX allows arbitrarily sized nonces, and doesn't require precommitment to + * any lengths, and allows header data to be processed independently of any + * message. It's basically about as good as a rate-1/2 scheme is going to + * be. + */ + +#ifndef CATACOMB_EAX_H +#define CATACOMB_EAX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +#ifndef CATACOMB_GAEAD_H +# include "gaead.h" +#endif + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @EAX_DECL@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates declarations for EAX authenticated-encryption mode. + */ + +#define EAX_DECL(PRE, pre) \ + \ +typedef struct pre##_eaxkey { \ + pre##_ctx ctx; /* Block cipher key */ \ + uint32 m0[PRE##_BLKSZ/4], m1[PRE##_BLKSZ/4]; /* Final OMAC masks */ \ + uint32 v0[PRE##_BLKSZ/4], /* OMAC tweak accumulators */ \ + v1[PRE##_BLKSZ/4], v2[PRE##_BLKSZ/4]; \ + uint32 z0[PRE##_BLKSZ/4], /* Empty-message tag values */ \ + z1[PRE##_BLKSZ/4], z2[PRE##_BLKSZ/4]; \ +} pre##_eaxkey; \ + \ +typedef struct pre##_eaxaadctx { \ + pre##_eaxkey k; /* Underlying key */ \ + uint32 a[PRE##_BLKSZ/4]; /* OMAC accumulator */ \ + octet b[PRE##_BLKSZ]; /* Input buffer */ \ + unsigned off; /* Length of stuff in buffer */ \ +} pre##_eaxaadctx; \ + \ +typedef struct pre##_eaxctx { \ + /* The buffer is split into two portions. The first N octets hold a \ + * chunk of ciphertext, which will be fed into the OMAC calculation; \ + * the remaining BLKSZ - N octets hold E_K(C), which is the XOR mask \ + * to apply to the plaintext or ciphertext. \ + */ \ + pre##_eaxkey k; /* Underlying key */ \ + uint32 c[PRE##_BLKSZ/4]; /* Current counter value */ \ + uint32 c0[PRE##_BLKSZ/4]; /* Initial counter */ \ + uint32 a[PRE##_BLKSZ]; /* OMAC accumulator */ \ + octet b[PRE##_BLKSZ]; /* Ciphertext/mask buffer */ \ + unsigned off; /* Crossover point in buffer */ \ +} pre##_eaxctx; \ + \ +extern const octet pre##_eaxnoncesz[], pre##_eaxtagsz[]; \ + \ +/* --- @pre_eaxsetkey@ --- * \ + * \ + * Arguments: @pre_eaxkey *key@ = pointer to key block to fill in \ + * @const void *k@ = pointer to key material \ + * @size_t ksz@ = size of key material \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an EAX key block. \ + */ \ + \ +extern void pre##_eaxsetkey(pre##_eaxkey */*key*/, \ + const void */*k*/, size_t /*ksz*/); \ + \ +/* --- @pre_eaxaadinit@ --- * \ + * \ + * Arguments: @pre_eaxaadctx *aad@ = pointer to AAD context \ + * @const pre_eaxkey *key@ = pointer to key block \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an EAX AAD (`additional authenticated \ + * data') context associated with a given key. AAD \ + * contexts can be copied and/or reused, saving time if \ + * the AAD for a number of messages has a common prefix. \ + * \ + * The @key@ doesn't need to be kept around, though \ + * usually there'll at least be another copy in some EAX \ + * operation context because the AAD on its own isn't much \ + * good. \ + */ \ + \ +extern void pre##_eaxaadinit(pre##_eaxaadctx */*aad*/, \ + const pre##_eaxkey */*key*/); \ + \ +/* --- @pre_eaxaadhash@ --- * \ + * \ + * Arguments: @pre_eaxaadctx *aad@ = pointer to AAD context \ + * @const void *p@ = pointer to AAD material \ + * @size_t sz@ = length of AAD material \ + * \ + * Returns: --- \ + * \ + * Use: Feeds AAD into the context. \ + */ \ + \ +extern void pre##_eaxaadhash(pre##_eaxaadctx */*aad*/, \ + const void */*p*/, size_t /*sz*/); \ + \ +/* --- @pre_eaxinit@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to EAX context \ + * @const pre_eaxkey *key@ = pointer to key block \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: --- \ + * \ + * Use: Initialize an EAX operation context with a given key. \ + * \ + * The original key needn't be kept around any more. \ + */ \ + \ +extern void pre##_eaxinit(pre##_eaxctx */*ctx*/, \ + const pre##_eaxkey */*k*/, \ + const void */*n*/, size_t /*nsz*/); \ + \ +/* --- @pre_eaxreinit@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to EAX context \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: --- \ + * \ + * Use: Reinitialize an EAX operation context, changing the \ + * nonce. \ + */ \ + \ +extern void pre##_eaxreinit(pre##_eaxctx */*ctx*/, \ + const void */*n*/, size_t /*nsz*/); \ + \ +/* --- @pre_eaxencrypt@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to EAX operation context \ + * @const void *src@ = pointer to plaintext message chunk \ + * @size_t sz@ = size of the plaintext \ + * @buf *dst@ = a buffer to write the ciphertext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Encrypts a chunk of a plaintext message, writing a \ + * chunk of ciphertext to the output buffer and updating \ + * the operation state. \ + * \ + * For EAX, we always write a ciphertext chunk the same \ + * size as the plaintext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +extern int pre##_eaxencrypt(pre##_eaxctx */*ctx*/, \ + const void */*src*/, size_t /*sz*/, \ + buf */*dst*/); \ + \ +/* --- @pre_eaxdecrypt@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to EAX operation context \ + * @const void *src@ = pointer to ciphertext message chunk \ + * @size_t sz@ = size of the ciphertext \ + * @buf *dst@ = a buffer to write the plaintext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Decrypts a chunk of a ciphertext message, writing a \ + * chunk of plaintext to the output buffer and updating \ + * the operation state. \ + * \ + * For EAX, we always write a plaintext chunk the same \ + * size as the ciphertext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +extern int pre##_eaxdecrypt(pre##_eaxctx */*ctx*/, \ + const void */*src*/, size_t /*sz*/, \ + buf */*dst*/); \ + \ +/* --- @pre_eaxencryptdone@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to an EAX context \ + * @const pre_eaxaadctx *aad@ = pointer to AAD context, or \ + * null \ + * @buf *dst@ = buffer for remaining ciphertext \ + * @void *tag@ = where to write the tag \ + * @size_t tsz@ = length of tag to store \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Completes an EAX encryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. EAX doesn't buffer ciphertext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +extern int pre##_eaxencryptdone(pre##_eaxctx */*ctx*/, \ + const pre##_eaxaadctx */*aad*/, \ + buf */*dst*/, \ + void */*tag*/, size_t /*tsz*/); \ + \ +/* --- @pre_eaxdecryptdone@ --- * \ + * \ + * Arguments: @pre_eaxctx *ctx@ = pointer to an EAX context \ + * @const pre_eaxaadctx *aad@ = pointer to AAD context, or \ + * null \ + * @buf *dst@ = buffer for remaining plaintext \ + * @const void *tag@ = tag to verify \ + * @size_t tsz@ = length of tag \ + * \ + * Returns: @+1@ for complete success; @0@ if tag verification \ + * failed; @-1@ for other kinds of errors. \ + * \ + * Use: Completes an EAX decryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. EAX doesn't buffer plaintext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +extern int pre##_eaxdecryptdone(pre##_eaxctx */*ctx*/, \ + const pre##_eaxaadctx */*aad*/, \ + buf */*dst*/, \ + const void */*tag*/, size_t /*tsz*/); \ + \ +/* --- Generic AEAD interface --- */ \ + \ +extern const gcaead pre##_eax; + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/ecb-def.h b/symm/ecb-def.h index 568ffa1e..c69790de 100644 --- a/symm/ecb-def.h +++ b/symm/ecb-def.h @@ -80,9 +80,7 @@ */ \ \ void pre##_ecbsetkey(pre##_ecbctx *ctx, const pre##_ctx *k) \ -{ \ - ctx->ctx = *k; \ -} \ + { ctx->ctx = *k; } \ \ /* --- @pre_ecbinit@ --- * \ * \ @@ -98,11 +96,9 @@ void pre##_ecbsetkey(pre##_ecbctx *ctx, const pre##_ctx *k) \ */ \ \ void pre##_ecbinit(pre##_ecbctx *ctx, \ - const void *key, size_t sz, \ - const void *iv) \ -{ \ - pre##_init(&ctx->ctx, key, sz); \ -} \ + const void *key, size_t sz, \ + const void *iv) \ + { pre##_init(&ctx->ctx, key, sz); } \ \ /* --- @pre_ecbencrypt@ --- * \ * \ @@ -120,16 +116,19 @@ void pre##_ecbinit(pre##_ecbctx *ctx, \ */ \ \ void pre##_ecbencrypt(pre##_ecbctx *ctx, \ - const void *src, void *dest, \ - size_t sz) \ + const void *src, void *dest, \ + size_t sz) \ { \ const octet *s = src; \ octet *d = dest; \ + uint32 t[PRE##_BLKSZ/4]; \ + octet b[PRE##_BLKSZ]; \ + octet y; \ + unsigned i; \ \ - /* --- Empty blocks are trivial --- */ \ + /* --- Empty blocks are trivial, and ECB is stateless --- */ \ \ - if (!sz) \ - return; \ + if (!sz || !d) return; \ \ /* --- Short blocks aren't allowed in ECB --- * \ * \ @@ -146,19 +145,11 @@ void pre##_ecbencrypt(pre##_ecbctx *ctx, \ * Hopefully... \ */ \ \ - while (sz >= 2 * PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ - uint32 x[PRE##_BLKSZ / 4]; \ - if (!s) \ - BLKC_ZERO(PRE, x); \ - else { \ - BLKC_LOAD(PRE, x, s); \ - s += PRE##_BLKSZ; \ - } \ - pre##_eblk(&ctx->ctx, x, x); \ - if (d) { \ - BLKC_STORE(PRE, d, x); \ - d += PRE##_BLKSZ; \ - } \ + while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ + if (!s) BLKC_ZERO(PRE, t); \ + else { BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ; } \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, d, t); d += PRE##_BLKSZ; \ sz -= PRE##_BLKSZ; \ } \ \ @@ -168,9 +159,6 @@ void pre##_ecbencrypt(pre##_ecbctx *ctx, \ */ \ \ if (sz) { \ - uint32 x[PRE##_BLKSZ / 4]; \ - octet b[PRE##_BLKSZ]; \ - unsigned i; \ \ /* --- Let @sz@ be the size of the partial block --- */ \ \ @@ -183,14 +171,10 @@ void pre##_ecbencrypt(pre##_ecbctx *ctx, \ * out yet, because I've not read the partial plaintext block. \ */ \ \ - if (!s) \ - BLKC_ZERO(PRE, x); \ - else { \ - BLKC_LOAD(PRE, x, s); \ - s += PRE##_BLKSZ; \ - } \ - pre##_eblk(&ctx->ctx, x, x); \ - BLKC_STORE(PRE, b, x); \ + if (!s) BLKC_ZERO(PRE, t); \ + else { BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ; } \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, b, t); \ \ /* --- Second stage --- * \ * \ @@ -199,15 +183,11 @@ void pre##_ecbencrypt(pre##_ecbctx *ctx, \ * ciphertext block. \ */ \ \ - if (d) d += PRE##_BLKSZ; \ - for (i = 0; i < sz; i++) { \ - register octet y = b[i]; \ - b[i] = s[i]; \ - if (d) d[i] = y; \ - } \ - BLKC_LOAD(PRE, x, b); \ - pre##_eblk(&ctx->ctx, x, x); \ - if (d) BLKC_STORE(PRE, d - PRE##_BLKSZ, x); \ + d += PRE##_BLKSZ; \ + for (i = 0; i < sz; i++) { y = b[i]; b[i] = s[i]; d[i] = y; } \ + BLKC_LOAD(PRE, t, b); \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, d - PRE##_BLKSZ, t); \ } \ \ /* --- Done --- */ \ @@ -236,11 +216,14 @@ void pre##_ecbdecrypt(pre##_ecbctx *ctx, \ { \ const octet *s = src; \ octet *d = dest; \ + uint32 t[PRE##_BLKSZ/4]; \ + octet b[PRE##_BLKSZ]; \ + octet y; \ + unsigned i; \ \ /* --- Empty blocks are trivial --- */ \ \ - if (!sz) \ - return; \ + if (!sz) return; \ \ /* --- Short blocks aren't allowed in ECB --- * \ * \ @@ -256,13 +239,10 @@ void pre##_ecbdecrypt(pre##_ecbctx *ctx, \ * Each block is just handed to the block cipher in turn. \ */ \ \ - while (sz >= 2 * PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ - uint32 x[PRE##_BLKSZ / 4]; \ - BLKC_LOAD(PRE, x, s); \ - pre##_dblk(&ctx->ctx, x, x); \ - BLKC_STORE(PRE, d, x); \ - s += PRE##_BLKSZ; \ - d += PRE##_BLKSZ; \ + while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ + BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ; \ + pre##_dblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, d, t); d += PRE##_BLKSZ; \ sz -= PRE##_BLKSZ; \ } \ \ @@ -272,9 +252,6 @@ void pre##_ecbdecrypt(pre##_ecbctx *ctx, \ */ \ \ if (sz) { \ - uint32 x[PRE##_BLKSZ / 4]; \ - octet b[PRE##_BLKSZ]; \ - unsigned i; \ \ /* --- Let @sz@ be the size of the partial block --- */ \ \ @@ -286,9 +263,9 @@ void pre##_ecbdecrypt(pre##_ecbctx *ctx, \ * is carried over for the next encryption operation. \ */ \ \ - BLKC_LOAD(PRE, x, s); \ - pre##_dblk(&ctx->ctx, x, x); \ - BLKC_STORE(PRE, b, x); \ + BLKC_LOAD(PRE, t, s); \ + pre##_dblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, b, t); \ \ /* --- Second stage --- * \ * \ @@ -299,14 +276,10 @@ void pre##_ecbdecrypt(pre##_ecbctx *ctx, \ \ s += PRE##_BLKSZ; \ d += PRE##_BLKSZ; \ - for (i = 0; i < sz; i++) { \ - register octet y = s[i]; \ - d[i] = b[i]; \ - b[i] = y; \ - } \ - BLKC_LOAD(PRE, x, b); \ - pre##_dblk(&ctx->ctx, x, x); \ - BLKC_STORE(PRE, d - PRE##_BLKSZ, x); \ + for (i = 0; i < sz; i++) { y = s[i]; d[i] = b[i]; b[i] = y; } \ + BLKC_LOAD(PRE, t, b); \ + pre##_dblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, d - PRE##_BLKSZ, t); \ } \ \ /* --- Done --- */ \ @@ -332,23 +305,13 @@ static gcipher *ginit(const void *k, size_t sz) \ } \ \ static void gencrypt(gcipher *c, const void *s, void *t, size_t sz) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_ecbencrypt(&g->k, s, t, sz); \ -} \ + { gctx *g = (gctx *)c; pre##_ecbencrypt(&g->k, s, t, sz); } \ \ static void gdecrypt(gcipher *c, const void *s, void *t, size_t sz) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_ecbdecrypt(&g->k, s, t, sz); \ -} \ + { gctx *g = (gctx *)c; pre##_ecbdecrypt(&g->k, s, t, sz); } \ \ static void gdestroy(gcipher *c) \ -{ \ - gctx *g = (gctx *)c; \ - BURN(*g); \ - S_DESTROY(g); \ -} \ + { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); } \ \ static const gcipher_ops gops = { \ &pre##_ecb, \ @@ -368,9 +331,7 @@ ECB_TESTX(PRE, pre, name, fname) #ifdef TEST_RIG -#include - -#include "daftstory.h" +#include "modes-test.h" /* --- @ECB_TEST@ --- * * @@ -381,85 +342,28 @@ ECB_TESTX(PRE, pre, name, fname) #define ECB_TESTX(PRE, pre, name, fname) \ \ -/* --- Initial plaintext for the test --- */ \ - \ -static const octet text[] = TEXT; \ +static pre##_ctx key; \ +static pre##_ecbctx ctx; \ \ -/* --- Key and IV to use --- */ \ +static void pre##_ecb_test_setup(const octet *k, size_t ksz) \ + { pre##_init(&key, k, ksz); pre##_ecbsetkey(&ctx, &key); } \ \ -static const octet key[] = KEY; \ -static const octet iv[] = IV; \ +static void pre##_ecb_test_reset(const octet *iv) \ + { ; } \ \ -/* --- Buffers for encryption and decryption output --- */ \ +static void pre##_ecb_test_enc(const octet *s, octet *d, size_t sz) \ + { pre##_ecbencrypt(&ctx, s, d, sz); } \ \ -static octet ct[sizeof(text)]; \ -static octet pt[sizeof(text)]; \ +static void pre##_ecb_test_dec(const octet *s, octet *d, size_t sz) \ + { pre##_ecbdecrypt(&ctx, s, d, sz); } \ \ -static void hexdump(const octet *p, size_t sz, size_t off) \ +int main(int argc, char *argv[]) \ { \ - const octet *q = p + sz; \ - for (sz = 0; p < q; p++, sz++) { \ - printf("%02x", *p); \ - if ((off + sz + 1) % PRE##_BLKSZ == 0) \ - putchar(':'); \ - } \ -} \ - \ -int main(void) \ -{ \ - size_t sz = 0, rest; \ - pre##_ecbctx ctx; \ - int status = 0; \ - int done = 0; \ - \ - size_t keysz = PRE##_KEYSZ ? \ - PRE##_KEYSZ : strlen((const char *)key); \ - \ - fputs(name "-ecb: ", stdout); \ - \ - pre##_ecbinit(&ctx, key, keysz, iv); \ - \ - while (sz <= sizeof(text)) { \ - rest = sizeof(text) - sz; \ - if ((sz != 0 && sz < PRE##_BLKSZ) || \ - (rest != 0 && rest < PRE##_BLKSZ)) \ - goto next; \ - memcpy(ct, text, sizeof(text)); \ - pre##_ecbencrypt(&ctx, ct, ct, sz); \ - pre##_ecbencrypt(&ctx, ct + sz, ct + sz, rest); \ - memcpy(pt, ct, sizeof(text)); \ - pre##_ecbdecrypt(&ctx, pt, pt, sz); \ - pre##_ecbdecrypt(&ctx, pt + sz, pt + sz, rest); \ - if (memcmp(pt, text, sizeof(text)) == 0) { \ - done++; \ - if (sizeof(text) < 40 || done % 8 == 0) \ - fputc('.', stdout); \ - if (done % 480 == 0) \ - fputs("\n\t", stdout); \ - fflush(stdout); \ - } else { \ - printf("\nError (sz = %lu)\n", (unsigned long)sz); \ - status = 1; \ - printf("\tplaintext = "); hexdump(text, sz, 0); \ - printf(", "); hexdump(text + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\tciphertext = "); hexdump(ct, sz, 0); \ - printf(", "); hexdump(ct + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\trecovered text = "); hexdump(pt, sz, 0); \ - printf(", "); hexdump(pt + sz, rest, sz); \ - fputc('\n', stdout); \ - fputc('\n', stdout); \ - } \ - next: \ - if (sz < 63) \ - sz++; \ - else \ - sz += 9; \ - } \ - \ - fputs(status ? " failed\n" : " ok\n", stdout); \ - return (status); \ + return test_encmode(fname "-ecb", PRE##_KEYSZ, PRE##_BLKSZ, \ + PRE##_BLKSZ, TEMF_REFALIGN, \ + pre##_ecb_test_setup, pre##_ecb_test_reset, \ + pre##_ecb_test_enc, pre##_ecb_test_dec, \ + argc, argv); \ } #else diff --git a/symm/gaead.c b/symm/gaead.c new file mode 100644 index 00000000..45aeb614 --- /dev/null +++ b/symm/gaead.c @@ -0,0 +1,123 @@ +/* -*-c-*- + * + * Generic authenticated encryption interface + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "gaead.h" + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @gaead_encrypt@ --- * + * + * Arguments: @const gaead_key *k@ = the AEAD key, already prepared + * @const void *n@, @size_t nsz@ = nonce + * @const void *h@, @size_t hsz@ = additional `header' data + * @const void *m@, @size_t msz@ = message input + * @void *c@, @size_t *csz_input@ = ciphertext output + * @void *t@, @size_t tsz@ = tag output + * + * Returns: Zero on success, @-1@ if the output buffer is too small. + * + * Use: Encrypts and authenticates a message in a single operation. + * This just saves a bunch of messing about with the various + * @gaead_...@ objects. + * + * On entry, @*csz_inout@ should be the capacity of the + * ciphertext buffer; on exit, it will be updated with the + * actual size of ciphertext produced. The function will not + * fail if @*csz_inout >= msz + k->c->ohd@. + */ + +int gaead_encrypt(const gaead_key *k, const void *n, size_t nsz, + const void *h, size_t hsz, + const void *m, size_t msz, + void *c, size_t *csz_inout, + void *t, size_t tsz) +{ + gaead_enc *e = 0; + gaead_aad *a = 0; + buf b; + int rc; + + buf_init(&b, c, *csz_inout); + e = GAEAD_ENC(k, n, nsz, hsz, msz, tsz); if (!e) { rc = -1; goto end; } + if (hsz) { a = GAEAD_AAD(e); GAEAD_HASH(a, h, hsz); } + rc = GAEAD_ENCRYPT(e, m, msz, &b); if (rc) goto end; + rc = GAEAD_DONE(e, a, &b, t, tsz); +end: + if (rc >= 0) *csz_inout = BLEN(&b); + if (e) GAEAD_DESTROY(e); + if (a) GAEAD_DESTROY(a); + return (rc); +} + +/* --- @gaead_decrypt@ --- * + * + * Arguments: @const gaead_key *k@ = the AEAD key, already prepared + * @const void *n@, @size_t nsz@ = nonce + * @const void *h@, @size_t hsz@ = additional `header' data + * @const void *c@, @size_t csz@ = ciphertext input + * @void *m@, @size_t *msz_inout@ = message output + * @const void *t@, @size_t tsz@ = tag input + * + * Returns: @+1@ if everything is good; zero for authentication failure, + * @-1@ for other problems. + * + * Use: Decrypts and verifies a message in a single operation. + * This just saves a bunch of messing about with the various + * @gaead_...@ objects. + * + * On entry, @*msz_inout@ should be the capacity of the + * message buffer; on exit, it will be updated with the + * actual size of message produced. The function will not + * fail if @*msz_inout >= csz@. + */ + +int gaead_decrypt(const gaead_key *k, const void *n, size_t nsz, + const void *h, size_t hsz, + const void *c, size_t csz, + void *m, size_t *msz_inout, + const void *t, size_t tsz) +{ + gaead_dec *d = 0; + gaead_aad *a = 0; + buf b; + int rc; + + buf_init(&b, m, *msz_inout); + d = GAEAD_DEC(k, n, nsz, hsz, csz, tsz); if (!d) { rc = -1; goto end; } + if (hsz) { a = GAEAD_AAD(d); GAEAD_HASH(a, h, hsz); } + rc = GAEAD_DECRYPT(d, c, csz, &b); if (rc) goto end; + rc = GAEAD_DONE(d, a, &b, t, tsz); +end: + if (rc >= 0) *msz_inout = BLEN(&b); + if (d) GAEAD_DESTROY(d); + if (a) GAEAD_DESTROY(a); + return (rc); +} + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/symm/gaead.h b/symm/gaead.h new file mode 100644 index 00000000..33feb366 --- /dev/null +++ b/symm/gaead.h @@ -0,0 +1,394 @@ +/* -*-c-*- + * + * Generic authenticated encryption interface + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef CATACOMB_GAEAD_H +#define CATACOMB_GAEAD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include + +#ifndef CATACOMB_BUF_H +# include "buf.h" +#endif + +#ifndef CATACOMB_KEYSZ_H +# include "keysz.h" +#endif + +/*----- Generic AEAD interface --------------------------------------------*/ + +typedef struct gaead_key { + const struct gaead_keyops *ops; +} gaead_key; + +typedef struct gaead_enc { + const struct gaead_encops *ops; +} gaead_enc; + +typedef struct gaead_dec { + const struct gaead_decops *ops; +} gaead_dec; + +typedef struct gaead_aad { + const struct gaead_aadops *ops; +} gaead_aad; + +typedef struct gaead_keyops { + const struct gcaead *c; /* Pointer to AEAD class */ + + gaead_aad *(*aad)(const gaead_key */*k*/); + /* Return an AAD-hashing object for this key. Only available if + * the @AEADF_AADNDEP@ class flag is clear. + */ + + gaead_enc *(*enc)(const gaead_key */*k*/, + const void */*n*/, size_t /*nsz*/, + size_t /*hsz*/, size_t /*msz*/, size_t /*tsz*/); + /* Return a message encryption object for this key, with the given + * nonce. If the @AEADF_PCHSZ@, @AEADF_PCMSZ@ and/or @AEADF_PCTSZ@ + * class flags are set then the caller must provide the AAD length + * @hsz@, message length @msz@ and/or tag length @tsz@ respectively; + * otherwise these arguments will be ignored. + * + * The caller is expected to have ensured that the nonce and tag + * lengths are acceptable, e.g., by checking against the tables + * provided in the class object. Some unfortunate AEAD schemes have + * more complicated requirements: if the sizes are unacceptable in + * combination, this function returns null. + */ + + gaead_dec *(*dec)(const gaead_key */*k*/, + const void */*n*/, size_t /*nsz*/, + size_t /*hsz*/, size_t /*csz*/, size_t /*tsz*/); + /* Return a message encryption object for this key, with the given + * nonce. If the @AEADF_PCHSZ@, @AEADF_PCMSZ@ and/or @AEADF_PCTSZ@ + * class flags are set then the caller must provide the AAD length + * @hsz@, ciphertext length @csz@ and/or tag length @tsz@ + * respectively; otherwise these arguments will be ignored. + * + * The caller is expected to have ensured that the nonce and tag + * lengths are acceptable, e.g., by checking against the tables + * provided in the class object. Some unfortunate AEAD schemes have + * more complicated requirements: if the sizes are unacceptable in + * combination, this function returns null. + */ + + void (*destroy)(gaead_key */*k*/); + /* Destroy the key object. This will not invalidate AAD-hashing, + * encryption or decryption objects. + */ + +} gaead_keyops; + +typedef struct gaead_aadops { + const struct gcaead *c; /* Pointer to AEAD class */ + + gaead_aad *(*dup)(const gaead_aad */*a*/); + /* Return a new AAD-hashing object with a copy of this object's + * state. This is useful if the AAD for multiple messages shares a + * common prefix: the prefix can be processed once, and a copy + * created for each different suffix. Only available if the + * @AEADF_AADNDEP@ class flag is clear. + */ + + void (*hash)(gaead_aad */*a*/, const void */*h*/, size_t /*hsz*/); + /* Feed header (additional authenticated) data into the AAD-hashing + * object. If the @AEADF_NOAAD@ class flag is set then @hsz@ must be + * zero. + */ + + void (*destroy)(gaead_aad */*a*/); + /* Destroy the AAD-hashing object. */ + +} gaead_aadops; + +typedef struct gaead_encops { + const struct gcaead *c; /* Pointer to AEAD class */ + + gaead_aad *(*aad)(gaead_enc */*e*/); + /* Return a new AAD-hashing object for the current key and nonce. If + * the @AEADF_AADNDEP@ class flag is clear then this works just as if + * the @aad@ method on the key had been called instead: the new + * object is in fact independent of the nonce and can be used with + * any encryption or decryption operation. If @AEADF_AADNDEP@ is + * set, then the returned AAD-hashing object is specific to this + * encryption operation. If @AEADF_AADFIRST@ is also set, then all + * additional data must be hashed before any message data is + * presented for encryption. + */ + + int (*reinit)(gaead_enc */*e*/, const void */*n*/, size_t /*nsz*/, + size_t /*hsz*/, size_t /*msz*/, size_t /*tsz*/); + /* Reinitialize this object for a new encryption operation with a + * different nonce. The data lengths @hsz@, @msz@, and @tsz@ are as + * for the key @enc@ method. Returns zero on success. + * + * The caller is expected to have ensured that the nonce and tag + * lengths are acceptable, e.g., by checking against the tables + * provided in the class object. Some unfortunate AEAD schemes have + * more complicated requirements: if the sizes are unacceptable in + * combination, this function returns @-1@. + */ + + int (*encrypt)(gaead_enc */*e*/, const void */*m*/, size_t /*msz*/, + buf */*b*/); + /* Encrypt a chunk of data, writing the result to the output buffer + * @b@. This will succeed if @BLEFT(b) >= msz + e->c->bufsz@; + * otherwise it might fail. Failure doesn't affect the encryption + * operation's state. Returns zero on success, or @-1@ on failure. + */ + + int (*done)(gaead_enc */*e*/, const gaead_aad */*a*/, buf */*b*/, + void */*t*/, size_t /*tsz*/); + /* Completes encryption, returning the authentication tag for the + * message and any additional authenticated data accumulated in @a@. + * The pointer @a@ may be null if there is no AAD. If the + * @AEADF_AADNDEP@ class flag is set, and any header data has been + * provided to the operation's AAD-hashing object, then a pointer to + * this object must be provided as @a@. If @AEADF_AADNDEP@ is clear, + * then any AAD-hashing object for this key may be provided. + * Internally buffered ciphertext may be written to @b@. This will + * succeed if @BLEFT(b) >= e->c->bufsz@; otherwise it might fail. + * Failure doesn't affect the encryption operation's state. Returns + * zero on success, or @-1@ on failure. + */ + + void (*destroy)(gaead_enc */*e*/); + /* Destroy the encryption object. */ + +} gaead_encops; + +typedef struct gaead_decops { + const struct gcaead *c; /* Pointer to AEAD class */ + + gaead_aad *(*aad)(gaead_dec */*d*/); + /* Return a new AAD-hashing object for the current key and nonce. If + * the @AEADF_AADNDEP@ class flag is clear then this works just as if + * the @aad@ method on the key had been called instead: the new + * object is in fact independent of the nonce and can be used with + * any encryption or decryption operation. If @AEADF_AADNDEP@ is + * set, then the returned AAD-hashing object is specific to this + * decryption operation. If @AEADF_AADFIRST@ is also set, then all + * additional data must be hashed before any ciphertext is presented + * for decryption. + */ + + int (*reinit)(gaead_dec */*d*/, const void */*n*/, size_t /*nsz*/, + size_t /*hsz*/, size_t /*csz*/, size_t /*tsz*/); + /* Reinitialize this object for a new decryption operation with a + * different nonce. The data lengths @hsz@, @csz@, and @tsz@ are as + * for the key @dec@ method. + * + * The caller is expected to have ensured that the nonce and tag + * lengths are acceptable, e.g., by checking against the tables + * provided in the class object. Some unfortunate AEAD schemes have + * more complicated requirements: if the sizes are unacceptable in + * combination, this function returns @-1@. + */ + + int (*decrypt)(gaead_dec */*d*/, const void */*c*/, size_t /*csz*/, + buf */*b*/); + /* Decrypt a chunk of data, writing the result to the output buffer + * @b@. This will succeed if @BLEFT(b) >= msz + e->c->bufsz@; + * otherwise it might fail. Failure doesn't affect the decryption + * operation's state. Returns zero on success, or @-1@ on failure. + * + * CAUTION: the decrypted data may be inauthentic. Don't do anything + * risky with it until its tag has been verified. + */ + + int (*done)(gaead_dec */*d*/, const gaead_aad */*a*/, buf */*b*/, + const void */*t*/, size_t /*tsz*/); + /* Completes decryption, verifying the authentication tag for the + * message and any additional authenticated data accumulated in @a@. + * The pointer @a@ may be null if there is no AAD. If the + * @AEADF_AADNDEP@ class flag is set, and any header data has been + * provided to the operation's AAD-hashing object, then a pointer to + * this object must be provided as @a@. If @AEADF_AADNDEP@ is clear, + * then any AAD-hashing object for this key may be provided. + * Internally buffered plaintext may be written to @b@. This will + * succeed if @BLEFT(b) >= e->c->bufsz@; otherwise it might fail. + * Failure doesn't affect the decryption operation's state. Returns + * @+1@ on success, @0@ on verification failure, or @-1@ on other + * kinds of failures. + */ + + void (*destroy)(gaead_dec */*d*/); + /* Destroy the decryption object. */ + +} gaead_decops; + +typedef struct gcaead { + const char *name; /* AEAD scheme name */ + const octet *keysz; /* Acceptable keys-size table */ + const octet *noncesz; /* Acceptable nonce-size table */ + const octet *tagsz; /* Acceptable tag-size table */ + size_t blksz; /* Block size, or zero if none */ + unsigned bufsz; /* Maximum extra msg/ct output */ + unsigned ohd; /* Maximum encryption overhead */ + unsigned f; /* Various other flags */ +#define AEADF_PCHSZ 1u /* Precommit to AAD size */ +#define AEADF_PCMSZ 2u /* Precommit to message size */ +#define AEADF_PCTSZ 4u /* Precommit to tag size */ +#define AEADF_AADNDEP 8u /* AAD hash is nonce-dependent */ +#define AEADF_AADFIRST 16u /* AAD must precede msg/ct */ +#define AEADF_NOAAD 32u /* AAD is not permitted */ + + gaead_key *(*key)(const void */*k*/, size_t /*ksz*/); + /* Return a key object (above) with the given key material. */ + + int (*szok)(size_t /*nsz*/, size_t /*hsz*/, + size_t /*msz*/, size_t /*tsz*/); + /* Return true (nonzero) if the given collection of sizes for nonce, + * header, message, and tag are acceptable in combination. Mostly + * this will be true if the nonce length and tag size are are + * acceptable independently (and the header and message lengths are + * irrelevant), but some schemes are more awkward. + */ +} gcaead; + +#define GAEAD_KEY(cc, k, ksz) (cc)->key((k), (ksz)) +#define GAEAD_CLASS(obj) (obj)->ops->c +#define GAEAD_AAD(ked) (ked)->ops->aad((ked)) +#define GAEAD_REINIT(ed, n, nsz, hsz, msz, tsz) \ + (ed)->ops->reinit((ed), (n), (nsz), (hsz), (msz), (tsz)) +#define GAEAD_ENC(k, n, nsz, hsz, msz, tsz) \ + (k)->ops->enc((k), (n), (nsz), (hsz), (msz), (tsz)) +#define GAEAD_DEC(k, n, nsz, hsz, msz, tsz) \ + (k)->ops->dec((k), (n), (nsz), (hsz), (msz), (tsz)) +#define GAEAD_DUP(a) (a)->ops->dup((a)) +#define GAEAD_HASH(a, h, hsz) (a)->ops->hash((a), (h), (hsz)) +#define GAEAD_ENCRYPT(e, m, msz, b) \ + (e)->ops->encrypt((e), (m), (msz), (b)) +#define GAEAD_DECRYPT(d, c, csz, b) \ + (d)->ops->decrypt((d), (c), (csz), (b)) +#define GAEAD_DONE(ed, aad, b, t, tsz) \ + (ed)->ops->done((ed), (aad), (b), (t), (tsz)) +#define GAEAD_DESTROY(obj) (obj)->ops->destroy((obj)) + +/*----- Functions provided ------------------------------------------------*/ + +/* --- @gaead_szokcommon@ --- * + * + * Arguments: @const gcaead *aec@ = pointer to AEAD class + * @size_t nsz@, @size_t hsz@, @size_t msz@, @size_t tsz@ = + * nonce, header, message, and tag sizes + * + * Returns: Nonzero if the sizes are acceptable to the AEAD scheme in + * combination. + * + * Use: Generic implementation for sensible AEAD schemes. + */ + +extern int gaead_szokcommon(const gcaead */*aec*/, + size_t /*nsz*/, size_t /*hsz*/, + size_t /*msz*/, size_t /*tsz*/); + +/* --- @gaead_encrypt@ --- * + * + * Arguments: @const gaead_key *k@ = the AEAD key, already prepared + * @const void *n@, @size_t nsz@ = nonce + * @const void *h@, @size_t hsz@ = additional `header' data + * @const void *m@, @size_t msz@ = message input + * @void *c@, @size_t *csz_input@ = ciphertext output + * @void *t@, @size_t tsz@ = tag output + * + * Returns: Zero on success, @-1@ if the output buffer is too small. + * + * Use: Encrypts and authenticates a message in a single operation. + * This just saves a bunch of messing about with the various + * @gaead_...@ objects. + * + * On entry, @*csz_inout@ should be the capacity of the + * ciphertext buffer; on exit, it will be updated with the + * actual size of ciphertext produced. The function will not + * fail if @*csz_inout >= msz + k->c->ohd@. + */ + +extern int gaead_encrypt(const gaead_key */*k*/, + const void */*n*/, size_t /*nsz*/, + const void */*h*/, size_t /*hsz*/, + const void */*m*/, size_t /*msz*/, + void */*c*/, size_t */*csz_inout*/, + void */*t*/, size_t /*tsz*/); + +/* --- @gaead_decrypt@ --- * + * + * Arguments: @const gaead_key *k@ = the AEAD key, already prepared + * @const void *n@, @size_t nsz@ = nonce + * @const void *h@, @size_t hsz@ = additional `header' data + * @const void *c@, @size_t csz@ = ciphertext input + * @void *m@, @size_t *msz_inout@ = message output + * @const void *t@, @size_t tsz@ = tag input + * + * Returns: @+1@ if everything is good; zero for authentication failure, + * @-1@ for other problems. + * + * Use: Decrypts and verifies a message in a single operation. + * This just saves a bunch of messing about with the various + * @gaead_...@ objects. + * + * On entry, @*msz_inout@ should be the capacity of the + * message buffer; on exit, it will be updated with the + * actual size of message produced. The function will not + * fail if @*msz_inout >= csz@. + */ + +extern int gaead_decrypt(const gaead_key */*k*/, + const void */*n*/, size_t /*nsz*/, + const void */*h*/, size_t /*hsz*/, + const void */*c*/, size_t /*csz*/, + void */*m*/, size_t */*msz_inout*/, + const void */*t*/, size_t /*tsz*/); + +/*----- Tables ------------------------------------------------------------*/ + +extern const gcaead *const gaeadtab[]; + +/* --- @gaead_byname@ --- * + * + * Arguments: @const char *p@ = pointer to name string + * + * Returns: The named AEAD class, or null. + */ + +extern const gcaead *gaead_byname(const char */*p*/); + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/gcm-arm-crypto.S b/symm/gcm-arm-crypto.S new file mode 100644 index 00000000..ddc714b3 --- /dev/null +++ b/symm/gcm-arm-crypto.S @@ -0,0 +1,718 @@ +/// -*- mode: asm; asm-comment-char: ?/ -*- +/// +/// GCM acceleration for ARM processors +/// +/// (c) 2019 Straylight/Edgeware +/// + +///----- Licensing notice --------------------------------------------------- +/// +/// This file is part of Catacomb. +/// +/// Catacomb is free software: you can redistribute it and/or modify it +/// under the terms of the GNU Library General Public License as published +/// by the Free Software Foundation; either version 2 of the License, or +/// (at your option) any later version. +/// +/// Catacomb is distributed in the hope that it will be useful, but +/// WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +/// Library General Public License for more details. +/// +/// You should have received a copy of the GNU Library General Public +/// License along with Catacomb. If not, write to the Free Software +/// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +/// USA. + +///-------------------------------------------------------------------------- +/// Preliminaries. + +#include "config.h" +#include "asm-common.h" + + .arch armv8-a + .fpu crypto-neon-fp-armv8 + + .text + +///-------------------------------------------------------------------------- +/// Multiplication macros. + + // The good news is that we have a fancy instruction to do the + // multiplications. The bad news is that it's not particularly well- + // suited to the job. + // + // For one thing, it only does a 64-bit multiplication, so in general + // we'll need to synthesize the full-width multiply by hand. For + // another thing, it doesn't help with the reduction, so we have to + // do that by hand too. And, finally, GCM has crazy bit ordering, + // and the instruction does nothing useful for that at all. + // + // Focusing on that last problem first: the bits aren't in monotonic + // significance order unless we permute them. If we reverse the byte + // order, then we'll have the bits in monotonic order, but backwards, + // so the degree-0 coefficient will be in the most-significant bit. + // + // This is less of a difficulty than it seems at first, because + // algebra. Suppose we are given u = SUM_{0<=i + +#include +#include + +#ifndef CATACOMB_ARENA_H +# include "arena.h" +#endif + +#ifndef CATACOMB_BLKC_H +# include "blkc.h" +#endif + +#ifndef CATACOMB_CT_H +# include "ct.h" +#endif + +#ifndef CATACOMB_KEYSZ_H +# include "keysz.h" +#endif + +#ifndef CATACOMB_PARANOIA_H +# include "paranoia.h" +#endif + +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + +/*----- Type definitions --------------------------------------------------*/ + +typedef struct gcm_params { + unsigned f; /* flags */ +#define GCMF_SWAP 1u /* swap byte order? */ + unsigned n; /* number of words in block */ + uint32 poly; /* selected polynomial mask */ +} gcm_params; + +/*----- Utilities ---------------------------------------------------------*/ + +/* Supported block sizes. */ +#define GCM_WIDTHS(_) _(64) _(96) _(128) _(192) _(256) +#define GCM_NMAX 8 + +/* Polynomial tails for the supported block sizes. */ +#define GCM_POLY_64 0xd8000000 +#define GCM_POLY_96 0x82600000 +#define GCM_POLY_128 0xe1000000 +#define GCM_POLY_192 0xe1000000 +#define GCM_POLY_256 0xa4200000 + +/* Determine whether to set the @GCMF_SWAP@ flag. */ +#define GCM_SWAP_L GCMF_SWAP +#define GCM_SWAP_B 0 + +/* --- @gcm_mktable@ --- * + * + * Arguments: @const gcm_params *p@ = pointer to the parameters + * @uint32 *ktab@ = where to write the table; there must be + * space for %$32 n$% $%n$%-word entries, i.e., + * %$32 n^2$% 32-bit words in total, where %$n$% is + * @p->n@, the block size in words + * @const uint32 *k@ = input field element + * + * Returns: --- + * + * Use: Construct a table for use by @gcm_mulk_...@ below, to + * multiply (vaguely) efficiently by @k@. + */ + +extern void gcm_mktable(const gcm_params */*p*/, + uint32 */*ktab*/, const uint32 */*k*/); + +/* --- @gcm_mulk_N{b,l}@ --- * + * + * Arguments: @uint32 *a@ = accumulator to multiply + * @const uint32 *ktab@ = table constructed by @gcm_mktable@ + * + * Returns: --- + * + * Use: Multiply @a@ by @k@ (implicitly represented in @ktab@), + * updating @a@ in-place. There are separate functions for each + * supported block size and endianness because this is the + * function whose performance actually matters. + */ + +#define GCM_DECL_MULK(nbits) \ + extern void gcm_mulk_##nbits##b(uint32 */*a*/, const uint32 */*ktab*/); \ + extern void gcm_mulk_##nbits##l(uint32 */*a*/, const uint32 */*ktab*/); +GCM_WIDTHS(GCM_DECL_MULK) +#undef GCM_DECL_MULK + +/* Dispatch to the appropriate variant of @gcm_mulk@. */ +#define GCM_MULK(PRE, a, ktab) \ + BLKC_GLUE(GCM_MULK_, BLKC_ENDIAN(PRE))(BLKC_BITS(PRE), a, ktab) +#define GCM_MULK_B(nbits, a, ktab) \ + BLKC_GLUE(BLKC_GLUE(gcm_mulk_, nbits), b)(a, ktab) +#define GCM_MULK_L(nbits, a, ktab) \ + BLKC_GLUE(BLKC_GLUE(gcm_mulk_, nbits), l)(a, ktab) + +/* --- @gcm_ghashdone@ --- * + * + * Arguments: @const gcm_params *p@ = pointer to the parameters + * @uint32 *a@ = GHASH accumulator + * @const uint32 *ktab@ = multiplication table, built by + * @gcm_mktable@ + * @unsigned long xblocks, yblocks@ = number of whole blocks in + * the two inputs + * @unsigned xbytes, ybytes@ = number of trailing bytes in the + * two inputs + * + * Returns: --- + * + * Use: Finishes a GHASH operation by appending the appropriately + * encoded lengths of the two constituent messages. + */ + +extern void gcm_ghashdone(const gcm_params */*p*/, + uint32 */*a*/, const uint32 */*ktab*/, + unsigned long /*xblocks*/, unsigned /*xbytes*/, + unsigned long /*yblocks*/, unsigned /*ybytes*/); + +/* --- @gcm_concat@ --- * + * + * Arguments: @const gcm_params *p@ = pointer to the parameters + * @uint32 *z@ = GHASH accumulator for suffix, updated + * @const uint32 *x@ = GHASH accumulator for prefix + * @const uint32 *ktab@ = multiplication table, built by + * @gcm_mktable@ + * @unsigned long n@ = length of suffix in whole blocks + * + * Returns: --- + * + * Use: On entry, @x@ and @z@ are the results of hashing two strings + * %$a$% and %$b$%, each a whole number of blocks long; in + * particular, %$b$% is @n@ blocks long. On exit, @z@ is + * updated to be the hash of %$a \cat b$%. + */ + +extern void gcm_concat(const gcm_params */*p*/, + uint32 */*z*/, const uint32 */*x*/, + const uint32 */*ktab*/, unsigned long /*n*/); + +/* Step the counter using GCM's strange only-the-last-32-bits convention. */ +#define GCM_STEP(PRE, w) BLKC_GLUE(GCM_STEP_, BLKC_ENDIAN(PRE))(PRE, w) +#define GCM_STEP_B(PRE, w) GCM_STEP_X(PRE, BLKC_ID, w) +#define GCM_STEP_L(PRE, w) GCM_STEP_X(PRE, ENDSWAP32, w) +#define GCM_STEP_X(PRE, op, w) do { \ + BLKC_W(w); \ + _w[PRE##_BLKSZ/4 - 1] = op(op(_w[PRE##_BLKSZ/4 - 1]) + 1); \ +} while (0) + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @GCM_DEF@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates an implementation for the GCM authenticated- + * encryption mode. + */ + +#define GCM_DEF(PRE, pre) GCM_DEFX(PRE, pre, #pre, #pre) + +#define GCM_DEFX(PRE, pre, name, fname) \ + \ +static const gcm_params pre##_gcmparams = { \ + BLKC_GLUE(GCM_SWAP_, BLKC_ENDIAN(PRE)), \ + PRE##_BLKSZ/4, \ + BLKC_GLUE(GCM_POLY_, BLKC_BITS(PRE)) \ +}; \ + \ +const octet \ + pre##_gcmnoncesz[] = { KSZ_ANY, PRE##_BLKSZ - 4 }, \ + pre##_gcmtagsz[] = { KSZ_RANGE, PRE##_BLKSZ, 0, PRE##_BLKSZ, 1 }; \ + \ +static const rsvr_policy pre##_gcmpolicy = { 0, PRE##_BLKSZ, PRE##_BLKSZ }; \ + \ +/* --- @pre_gcmsetkey@ --- * \ + * \ + * Arguments: @pre_gcmkey *key@ = pointer to key block to fill in \ + * @const void *k@ = pointer to key material \ + * @size_t ksz@ = size of key material \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an GCM key block. \ + */ \ + \ +void pre##_gcmsetkey(pre##_gcmkey *key, const void *k, size_t ksz) \ +{ \ + uint32 t[PRE##_BLKSZ/4]; \ + \ + /* Initialize the block cipher. */ \ + pre##_init(&key->ctx, k, ksz); \ + \ + /* Set up the GHASH multiplication table. */ \ + BLKC_ZERO(PRE, t); pre##_eblk(&key->ctx, t, t); \ + gcm_mktable(&pre##_gcmparams, key->ktab, t); \ +} \ + \ +/* --- @pre_gcmaadinit@ --- * \ + * \ + * Arguments: @pre_gcmaadctx *aad@ = pointer to AAD context \ + * @const pre_gcmkey *key@ = pointer to key block \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an GCM AAD (`additional authenticated \ + * data') context associated with a given key. AAD \ + * contexts can be copied and/or reused, saving time if \ + * the AAD for a number of messages has a common prefix. \ + * \ + * The @key@ doesn't need to be kept around, though \ + * usually there'll at least be another copy in some GCM \ + * operation context because the AAD on its own isn't much \ + * good. \ + */ \ + \ +void pre##_gcmaadinit(pre##_gcmaadctx *aad, const pre##_gcmkey *key) \ + { aad->k = *key; aad->off = 0; aad->len = 0; BLKC_ZERO(PRE, aad->a); } \ + \ +/* --- @pre_gcmaadhash@ --- * \ + * \ + * Arguments: @pre_gcmaadctx *aad@ = pointer to AAD context \ + * @const void *p@ = pointer to AAD material \ + * @size_t sz@ = length of AAD material \ + * \ + * Returns: --- \ + * \ + * Use: Feeds AAD into the context. \ + */ \ + \ +void pre##_gcmaadhash(pre##_gcmaadctx *aad, const void *p, size_t sz) \ +{ \ + rsvr_state st; \ + const octet *q; \ + \ + rsvr_setup(&st, &pre##_gcmpolicy, aad->b, &aad->off, p, sz); \ + RSVR_DO(&st) while ((q = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \ + BLKC_XLOAD(PRE, aad->a, q); GCM_MULK(PRE, aad->a, aad->k.ktab); \ + aad->len++; \ + } \ +} \ + \ +/* --- @pre_gcminit@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to GCM context \ + * @const pre_gcmkey *key@ = pointer to key block \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: --- \ + * \ + * Use: Initialize an GCM operation context with a given key. \ + * \ + * The original key needn't be kept around any more. \ + */ \ + \ +void pre##_gcminit(pre##_gcmctx *ctx, const pre##_gcmkey *k, \ + const void *n, size_t nsz) \ + { ctx->k = *k; pre##_gcmreinit(ctx, n, nsz); } \ + \ +/* --- @pre_gcmreinit@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to GCM context \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: --- \ + * \ + * Use: Reinitialize an GCM operation context, changing the \ + * nonce. \ + */ \ + \ +void pre##_gcmreinit(pre##_gcmctx *ctx, const void *n, size_t nsz) \ +{ \ + octet b[PRE##_BLKSZ]; \ + const octet *q = n; \ + size_t nblocks; \ + unsigned i; \ + \ + /* Zero the counters. */ \ + ctx->off = 0; ctx->len = 0; \ + BLKC_ZERO(PRE, ctx->a); \ + \ + /* Calculate the initial counter from the nonce. */ \ + if (nsz == PRE##_BLKSZ - 4) { \ + /* Easy version: initialize the final word to 1 and copy the \ + * remaining words from the nonce. (The spec shows the nonce and \ + * counter the other way around for 64-bit block ciphers, but I'm \ + * sure this is just a mistake.) \ + */ \ + \ + for (i = 0; i < PRE##_BLKSZ/4 - 1; i++) \ + { ctx->c0[i] = BLKC_LOAD_E(PRE)(q); q += 4; } \ + ctx->c0[PRE##_BLKSZ/4 - 1] = BLKC_BWORD(PRE, 1); \ + } else { \ + /* Harder version: hash the nonce down with GHASH. */ \ + \ + BLKC_ZERO(PRE, ctx->c0); nblocks = 0; \ + while (nsz >= PRE##_BLKSZ) { \ + BLKC_XLOAD(PRE, ctx->c0, q); q += PRE##_BLKSZ; \ + GCM_MULK(PRE, ctx->c0, ctx->k.ktab); \ + nsz -= PRE##_BLKSZ; nblocks++; \ + } \ + if (nsz) { \ + memcpy(b, q, nsz); memset(b + nsz, 0, PRE##_BLKSZ - nsz); \ + BLKC_XLOAD(PRE, ctx->c0, b); \ + GCM_MULK(PRE, ctx->c0, ctx->k.ktab); \ + } \ + gcm_ghashdone(&pre##_gcmparams, ctx->c0, ctx->k.ktab, \ + 0, 0, nblocks, nsz); \ + } \ + \ + /* We must remember the initial counter for the final tag \ + * calculation. (I conjecture that storing the final counter instead \ + * would be just as secure, and require less state, but I've not \ + * proven this, and anyway it wouldn't interoperate.) Copy it to \ + * make the working counter. \ + */ \ + BLKC_MOVE(PRE, ctx->c, ctx->c0); \ +} \ + \ +/* --- @pre_gcmencrypt@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to GCM operation context \ + * @const void *src@ = pointer to plaintext message chunk \ + * @size_t sz@ = size of the plaintext \ + * @buf *dst@ = a buffer to write the ciphertext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Encrypts a chunk of a plaintext message, writing a \ + * chunk of ciphertext to the output buffer and updating \ + * the operation state. \ + * \ + * For GCM, we always write a ciphertext chunk the same \ + * size as the plaintext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +int pre##_gcmencrypt(pre##_gcmctx *ctx, \ + const void *src, size_t sz, buf *dst) \ +{ \ + rsvr_plan plan; \ + uint32 t[PRE##_BLKSZ/4]; \ + const octet *p = src; \ + octet *q, *r, y; \ + \ + /* Allocate space for the ciphertext. */ \ + if (sz) { q = buf_get(dst, sz); if (!q) return (-1); } \ + else q = 0; \ + \ + /* Determine the buffering plan. Our buffer is going to do double- \ + * duty here. The end portion is going to contain mask from the \ + * encrypted counter which we mix into the plaintext to encrypt it; \ + * the start portion, which originally mask bytes we've already used, \ + * will hold the output ciphertext, which will eventually be \ + * collected into the GHASH state. \ + */ \ + rsvr_mkplan(&plan, &pre##_gcmpolicy, ctx->off, sz); \ + \ + /* Initial portion, fulfilled from the buffer. If the buffer is \ + * empty, then that means that we haven't yet encrypted the current \ + * counter, so we should do that and advance it. \ + */ \ + if (plan.head) { \ + if (!ctx->off) { \ + GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + } \ + r = ctx->b + ctx->off; ctx->off += plan.head; \ + while (plan.head--) { y = *p++ ^ *r; *r++ = *q++ = y; } \ + } \ + \ + /* If we've filled up the buffer then we need to cycle the MAC and \ + * reset the offset. \ + */ \ + if (plan.from_rsvr) { \ + BLKC_XLOAD(PRE, ctx->a, ctx->b); GCM_MULK(PRE, ctx->a, ctx->k.ktab); \ + ctx->len++; ctx->off = 0; \ + } \ + \ + /* Now to process the main body of the input. */ \ + while (plan.from_input) { \ + GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \ + BLKC_XLOAD(PRE, t, p); p += PRE##_BLKSZ; \ + BLKC_STORE(PRE, q, t); q += PRE##_BLKSZ; \ + BLKC_XMOVE(PRE, ctx->a, t); GCM_MULK(PRE, ctx->a, ctx->k.ktab); \ + plan.from_input -= PRE##_BLKSZ; ctx->len++; \ + } \ + \ + /* Finally, deal with any final portion. If there is one, we know \ + * that the buffer is empty: we must have filled it above, or this \ + * would all count as `initial' data. \ + */ \ + if (plan.tail) { \ + GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + r = ctx->b; ctx->off += plan.tail; \ + while (plan.tail--) { y = *p++ ^ *r; *r++ = *q++ = y; } \ + } \ + \ + /* And we're done. */ \ + return (0); \ +} \ + \ +/* --- @pre_gcmdecrypt@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to GCM operation context \ + * @const void *src@ = pointer to ciphertext message chunk \ + * @size_t sz@ = size of the ciphertext \ + * @buf *dst@ = a buffer to write the plaintext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Decrypts a chunk of a ciphertext message, writing a \ + * chunk of plaintext to the output buffer and updating \ + * the operation state. \ + * \ + * For GCM, we always write a plaintext chunk the same \ + * size as the ciphertext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +int pre##_gcmdecrypt(pre##_gcmctx *ctx, \ + const void *src, size_t sz, buf *dst) \ +{ \ + rsvr_plan plan; \ + uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ]; \ + const octet *p = src; \ + octet *q, *r, y; \ + \ + /* Allocate space for the plaintext. */ \ + if (sz) { q = buf_get(dst, sz); if (!q) return (-1); } \ + else q = 0; \ + \ + /* Determine the buffering plan. Our buffer is going to do double- \ + * duty here. The end portion is going to contain mask from the \ + * encrypted counter which we mix into the plaintext to encrypt it; \ + * the start portion, which originally mask bytes we've already used, \ + * will hold the input ciphertext, which will eventually be \ + * collected into the GHASH state. \ + */ \ + rsvr_mkplan(&plan, &pre##_gcmpolicy, ctx->off, sz); \ + \ + /* Initial portion, fulfilled from the buffer. If the buffer is \ + * empty, then that means that we haven't yet encrypted the current \ + * counter, so we should do that and advance it. \ + */ \ + if (plan.head) { \ + if (!ctx->off) { \ + GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + } \ + r = ctx->b + ctx->off; ctx->off += plan.head; \ + while (plan.head--) { y = *p++; *q++ = y ^ *r; *r++ = y; } \ + } \ + \ + /* If we've filled up the buffer then we need to cycle the MAC and \ + * reset the offset. \ + */ \ + if (plan.from_rsvr) { \ + BLKC_XLOAD(PRE, ctx->a, ctx->b); GCM_MULK(PRE, ctx->a, ctx->k.ktab); \ + ctx->len++; ctx->off = 0; \ + } \ + \ + /* Now to process the main body of the input. */ \ + while (plan.from_input) { \ + GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \ + BLKC_LOAD(PRE, u, p); p += PRE##_BLKSZ; \ + BLKC_XSTORE(PRE, q, t, u); q += PRE##_BLKSZ; \ + BLKC_XMOVE(PRE, ctx->a, u); GCM_MULK(PRE, ctx->a, ctx->k.ktab); \ + plan.from_input -= PRE##_BLKSZ; ctx->len++; \ + } \ + \ + /* Finally, deal with any final portion. If there is one, we know \ + * that the buffer is empty: we must have filled it above, or this \ + * would all count as `initial' data. \ + */ \ + if (plan.tail) { \ + GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + r = ctx->b; ctx->off += plan.tail; \ + while (plan.tail--) { y = *p++; *q++ = y ^ *r; *r++ = y; } \ + } \ + \ + /* And we're done. */ \ + return (0); \ +} \ + \ +/* --- @pre_gcmtag@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to an GCM context \ + * @const pre_gcmaadctx *aad@ = pointer to AAD context, or \ + * null \ + * @octet *t@ = where to write a (full-length) tag \ + * \ + * Returns: --- \ + * \ + * Use: Finishes an GCM operation, by calculating the tag. \ + */ \ + \ +static void pre##_gcmtag(pre##_gcmctx *ctx, \ + const pre##_gcmaadctx *aad, octet *t) \ +{ \ + octet b[PRE##_BLKSZ]; \ + uint32 u[PRE##_BLKSZ/4]; \ + unsigned long n; \ + \ + /* Finish tagging the ciphertext. */ \ + if (ctx->off) { \ + memcpy(b, ctx->b, ctx->off); \ + memset(b + ctx->off, 0, PRE##_BLKSZ - ctx->off); \ + BLKC_XLOAD(PRE, ctx->a, b); GCM_MULK(PRE, ctx->a, ctx->k.ktab); \ + } \ + \ + /* If there's no AAD, because the pointer is null or no data was \ + * supplied, then apply that to the GHASH state. (Otherwise there's \ + * nothing to do here.) \ + */ \ + if (aad && (aad->len || aad->off)) { \ + BLKC_MOVE(PRE, u, aad->a); \ + if (aad->off) { \ + memcpy(b, aad->b, aad->off); \ + memset(b + aad->off, 0, PRE##_BLKSZ - aad->off); \ + BLKC_XLOAD(PRE, u, b); GCM_MULK(PRE, u, ctx->k.ktab); \ + } \ + n = ctx->len; if (ctx->off) n++; \ + gcm_concat(&pre##_gcmparams, ctx->a, u, ctx->k.ktab, n); \ + } \ + \ + /* Finish off the hash by appending the length. */ \ + gcm_ghashdone(&pre##_gcmparams, ctx->a, ctx->k.ktab, \ + aad ? aad->len : 0, aad ? aad->off : 0, \ + ctx->len, ctx->off); \ + \ + /* Mask the hash and store. */ \ + pre##_eblk(&ctx->k.ctx, ctx->c0, u); \ + BLKC_XSTORE(PRE, t, ctx->a, u); \ +} \ + \ +/* --- @pre_gcmencryptdone@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to an GCM context \ + * @const pre_gcmaadctx *aad@ = pointer to AAD context, or \ + * null \ + * @buf *dst@ = buffer for remaining ciphertext \ + * @void *tag@ = where to write the tag \ + * @size_t tsz@ = length of tag to store \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Completes an GCM encryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. GCM doesn't buffer ciphertext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +int pre##_gcmencryptdone(pre##_gcmctx *ctx, \ + const pre##_gcmaadctx *aad, buf *dst, \ + void *tag, size_t tsz) \ +{ \ + octet t[PRE##_BLKSZ]; \ + \ + if (tsz > PRE##_BLKSZ) return (-1); \ + if (!BOK(dst)) return (-1); \ + pre##_gcmtag(ctx, aad, t); memcpy(tag, t, tsz); \ + return (0); \ +} \ + \ +/* --- @pre_gcmdecryptdone@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to an GCM context \ + * @const pre_gcmaadctx *aad@ = pointer to AAD context, or \ + * null \ + * @buf *dst@ = buffer for remaining plaintext \ + * @const void *tag@ = tag to verify \ + * @size_t tsz@ = length of tag \ + * \ + * Returns: @+1@ for complete success; @0@ if tag verification \ + * failed; @-1@ for other kinds of errors. \ + * \ + * Use: Completes an GCM decryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. GCM doesn't buffer plaintext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +int pre##_gcmdecryptdone(pre##_gcmctx *ctx, \ + const pre##_gcmaadctx *aad, buf *dst, \ + const void *tag, size_t tsz) \ +{ \ + octet t[PRE##_BLKSZ]; \ + \ + if (tsz > PRE##_BLKSZ) return (-1); \ + if (!BOK(dst)) return (-1); \ + pre##_gcmtag(ctx, aad, t); \ + if (!ct_memeq(tag, t, tsz)) return (0); \ + else return (+1); \ +} \ + \ +/* --- Generic AEAD interface --- */ \ + \ +typedef struct gactx { \ + gaead_aad a; \ + pre##_gcmaadctx aad; \ +} gactx; \ + \ +static gaead_aad *gadup(const gaead_aad *a) \ + { gactx *aad = S_CREATE(gactx); *aad = *(gactx *)a; return (&aad->a); } \ + \ +static void gahash(gaead_aad *a, const void *h, size_t hsz) \ + { gactx *aad = (gactx *)a; pre##_gcmaadhash(&aad->aad, h, hsz); } \ + \ +static void gadestroy(gaead_aad *a) \ + { gactx *aad = (gactx *)a; BURN(*aad); S_DESTROY(aad); } \ + \ +static const gaead_aadops gaops = \ + { &pre##_gcm, gadup, gahash, gadestroy }; \ + \ +static gaead_aad *gaad(const pre##_gcmkey *k) \ +{ \ + gactx *aad = S_CREATE(gactx); \ + aad->a.ops = &gaops; \ + pre##_gcmaadinit(&aad->aad, k); \ + return (&aad->a); \ +} \ + \ +typedef struct gectx { \ + gaead_enc e; \ + pre##_gcmctx ctx; \ +} gectx; \ + \ +static gaead_aad *geaad(gaead_enc *e) \ + { gectx *enc = (gectx *)e; return (gaad(&enc->ctx.k)); } \ + \ +static int gereinit(gaead_enc *e, const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gectx *enc = (gectx *)e; \ + \ + if (tsz > PRE##_BLKSZ) return (-1); \ + pre##_gcmreinit(&enc->ctx, n, nsz); \ + return (0); \ +} \ + \ +static int geenc(gaead_enc *e, const void *m, size_t msz, buf *b) \ +{ \ + gectx *enc = (gectx *)e; \ + return (pre##_gcmencrypt(&enc->ctx, m, msz, b)); \ +} \ + \ +static int gedone(gaead_enc *e, const gaead_aad *a, \ + buf *b, void *t, size_t tsz) \ +{ \ + gectx *enc = (gectx *)e; gactx *aad = (gactx *)a; \ + assert(!a || a->ops == &gaops); \ + return (pre##_gcmencryptdone(&enc->ctx, a ? &aad->aad : 0, b, t, tsz)); \ +} \ + \ +static void gedestroy(gaead_enc *e) \ + { gectx *enc = (gectx *)e; BURN(*enc); S_DESTROY(enc); } \ + \ +static const gaead_encops geops = \ + { &pre##_gcm, geaad, gereinit, geenc, gedone, gedestroy }; \ + \ +typedef struct gdctx { \ + gaead_dec d; \ + pre##_gcmctx ctx; \ +} gdctx; \ + \ +static gaead_aad *gdaad(gaead_dec *d) \ + { gdctx *dec = (gdctx *)d; return (gaad(&dec->ctx.k)); } \ + \ +static int gdreinit(gaead_dec *d, const void *n, size_t nsz, \ + size_t hsz, size_t csz, size_t tsz) \ +{ \ + gdctx *dec = (gdctx *)d; \ + \ + if (tsz > PRE##_BLKSZ) return (-1); \ + pre##_gcmreinit(&dec->ctx, n, nsz); \ + return (0); \ +} \ + \ +static int gddec(gaead_dec *d, const void *c, size_t csz, buf *b) \ +{ \ + gdctx *dec = (gdctx *)d; \ + return (pre##_gcmdecrypt(&dec->ctx, c, csz, b)); \ +} \ + \ +static int gddone(gaead_dec *d, const gaead_aad *a, \ + buf *b, const void *t, size_t tsz) \ +{ \ + gdctx *dec = (gdctx *)d; gactx *aad = (gactx *)a; \ + assert(!a || a->ops == &gaops); \ + return (pre##_gcmdecryptdone(&dec->ctx, a ? &aad->aad : 0, b, t, tsz)); \ +} \ + \ +static void gddestroy(gaead_dec *d) \ + { gdctx *dec = (gdctx *)d; BURN(*dec); S_DESTROY(dec); } \ + \ +static const gaead_decops gdops = \ + { &pre##_gcm, gdaad, gdreinit, gddec, gddone, gddestroy }; \ + \ +typedef struct gkctx { \ + gaead_key k; \ + pre##_gcmkey key; \ +} gkctx; \ + \ +static gaead_aad *gkaad(const gaead_key *k) \ + { gkctx *key = (gkctx *)k; return (gaad(&key->key)); } \ + \ +static gaead_enc *gkenc(const gaead_key *k, const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gkctx *key = (gkctx *)k; \ + gectx *enc = S_CREATE(gectx); \ + \ + enc->e.ops = &geops; \ + pre##_gcminit(&enc->ctx, &key->key, n, nsz); \ + return (&enc->e); \ +} \ + \ +static gaead_dec *gkdec(const gaead_key *k, const void *n, size_t nsz, \ + size_t hsz, size_t csz, size_t tsz) \ +{ \ + gkctx *key = (gkctx *)k; \ + gdctx *dec = S_CREATE(gdctx); \ + \ + dec->d.ops = &gdops; \ + pre##_gcminit(&dec->ctx, &key->key, n, nsz); \ + return (&dec->d); \ +} \ + \ +static void gkdestroy(gaead_key *k) \ + { gkctx *key = (gkctx *)k; BURN(*key); S_DESTROY(key); } \ + \ +static const gaead_keyops gkops = \ + { &pre##_gcm, gkaad, gkenc, gkdec, gkdestroy }; \ + \ +static gaead_key *gckey(const void *k, size_t ksz) \ +{ \ + gkctx *key = S_CREATE(gkctx); \ + key->k.ops = &gkops; \ + pre##_gcmsetkey(&key->key, k, ksz); \ + return (&key->k); \ +} \ + \ +const gcaead pre##_gcm = { \ + name "-gcm", \ + pre##_keysz, pre##_gcmnoncesz, pre##_gcmtagsz, \ + PRE##_BLKSZ, 0, 0, 0, \ + gckey \ +}; \ + \ +GCM_TESTX(PRE, pre, name, fname) + +/*----- Test rig ----------------------------------------------------------*/ + +#define GCM_TEST(PRE, pre) GCM_TESTX(PRE, pre, #pre, #pre) + +/* --- @GCM_TEST@ --- * + * + * Arguments: @PRE, pre@ = prefixes for the underlying block cipher + * + * Use: Standard test rig for GCM functions. + */ + +#ifdef TEST_RIG + +#include + +#include +#include +#include + +#define GCM_TESTX(PRE, pre, name, fname) \ + \ +static int gcmverify(dstr *v) \ +{ \ + pre##_gcmkey key; \ + pre##_gcmaadctx aad; \ + pre##_gcmctx ctx; \ + int ok = 1, win; \ + int i; \ + octet *p; \ + int szs[] = { 1, 7, 192, -1, 0 }, *ip; \ + size_t hsz, msz; \ + dstr d = DSTR_INIT, t = DSTR_INIT; \ + buf b; \ + \ + dstr_ensure(&d, v[4].len > v[3].len ? v[4].len : v[3].len); \ + dstr_ensure(&t, v[5].len); t.len = v[5].len; \ + \ + pre##_gcmsetkey(&key, v[0].buf, v[0].len); \ + \ + for (ip = szs; *ip; ip++) { \ + \ + pre##_gcminit(&ctx, &key, (octet *)v[1].buf, v[1].len); \ + \ + i = *ip; \ + hsz = v[2].len; \ + if (i == -1) i = hsz; \ + if (i > hsz) continue; \ + p = (octet *)v[2].buf; \ + pre##_gcmaadinit(&aad, &key); \ + while (hsz) { \ + if (i > hsz) i = hsz; \ + pre##_gcmaadhash(&aad, p, i); \ + p += i; hsz -= i; \ + } \ + \ + buf_init(&b, d.buf, d.sz); \ + i = *ip; \ + msz = v[3].len; \ + if (i == -1) i = msz; \ + if (i > msz) continue; \ + p = (octet *)v[3].buf; \ + while (msz) { \ + if (i > msz) i = msz; \ + if (pre##_gcmencrypt(&ctx, p, i, &b)) { \ + puts("!! gcmencrypt reports failure"); \ + goto fail_enc; \ + } \ + p += i; msz -= i; \ + } \ + \ + if (pre##_gcmencryptdone(&ctx, &aad, &b, (octet *)t.buf, t.len)) { \ + puts("!! gcmencryptdone reports failure"); \ + goto fail_enc; \ + } \ + d.len = BLEN(&b); \ + \ + if (d.len != v[4].len || \ + memcmp(d.buf, v[4].buf, v[4].len) != 0 || \ + memcmp(t.buf, v[5].buf, v[5].len) != 0) { \ + fail_enc: \ + printf("\nfail encrypt:\n\tstep = %i", *ip); \ + fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \ + fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \ + fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \ + fputs("\n\tmessage = ", stdout); type_hex.dump(&v[3], stdout); \ + fputs("\n\texp ct = ", stdout); type_hex.dump(&v[4], stdout); \ + fputs("\n\tcalc ct = ", stdout); type_hex.dump(&d, stdout); \ + fputs("\n\texp tag = ", stdout); type_hex.dump(&v[5], stdout); \ + fputs("\n\tcalc tag = ", stdout); type_hex.dump(&t, stdout); \ + putchar('\n'); \ + ok = 0; \ + } \ + \ + pre##_gcminit(&ctx, &key, (octet *)v[1].buf, v[1].len); \ + \ + buf_init(&b, d.buf, d.sz); \ + i = *ip; \ + msz = v[4].len; \ + if (i == -1) i = msz; \ + if (i > msz) continue; \ + p = (octet *)v[4].buf; \ + while (msz) { \ + if (i > msz) i = msz; \ + if (pre##_gcmdecrypt(&ctx, p, i, &b)) { \ + puts("!! gcmdecrypt reports failure"); \ + win = 0; goto fail_dec; \ + } \ + p += i; msz -= i; \ + } \ + \ + win = pre##_gcmdecryptdone(&ctx, &aad, &b, \ + (octet *)v[5].buf, v[5].len); \ + if (win < 0) { \ + puts("!! gcmdecryptdone reports failure"); \ + goto fail_dec; \ + } \ + d.len = BLEN(&b); \ + \ + if (d.len != v[3].len || !win || \ + memcmp(d.buf, v[3].buf, v[3].len) != 0) { \ + fail_dec: \ + printf("\nfail decrypt:\n\tstep = %i", *ip); \ + fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \ + fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \ + fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \ + fputs("\n\tciphertext = ", stdout); type_hex.dump(&v[4], stdout); \ + fputs("\n\texp pt = ", stdout); type_hex.dump(&v[3], stdout); \ + fputs("\n\tcalc pt = ", stdout); type_hex.dump(&d, stdout); \ + fputs("\n\ttag = ", stdout); type_hex.dump(&v[5], stdout); \ + printf("\n\tverify %s", win ? "ok" : "FAILED"); \ + putchar('\n'); \ + ok = 0; \ + } \ + } \ + \ + dstr_destroy(&d); dstr_destroy(&t); \ + return (ok); \ +} \ + \ +static test_chunk aeaddefs[] = { \ + { name "-gcm", gcmverify, \ + { &type_hex, &type_hex, &type_hex, &type_hex, \ + &type_hex, &type_hex, 0 } }, \ + { 0, 0, { 0 } } \ +}; \ + \ +int main(int argc, char *argv[]) \ +{ \ + ego(argv[0]); \ + test_run(argc, argv, aeaddefs, SRCDIR"/t/" fname); \ + return (0); \ +} + +#else +# define GCM_TESTX(PRE, pre, name, fname) +#endif + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/gcm-x86ish-pclmul.S b/symm/gcm-x86ish-pclmul.S new file mode 100644 index 00000000..e60b7cab --- /dev/null +++ b/symm/gcm-x86ish-pclmul.S @@ -0,0 +1,1073 @@ +/// -*- mode: asm; asm-comment-char: ?/ -*- +/// +/// GCM acceleration for x86 processors +/// +/// (c) 2018 Straylight/Edgeware +/// + +///----- Licensing notice --------------------------------------------------- +/// +/// This file is part of Catacomb. +/// +/// Catacomb is free software: you can redistribute it and/or modify it +/// under the terms of the GNU Library General Public License as published +/// by the Free Software Foundation; either version 2 of the License, or +/// (at your option) any later version. +/// +/// Catacomb is distributed in the hope that it will be useful, but +/// WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +/// Library General Public License for more details. +/// +/// You should have received a copy of the GNU Library General Public +/// License along with Catacomb. If not, write to the Free Software +/// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +/// USA. + +///-------------------------------------------------------------------------- +/// Preliminaries. + +#include "config.h" +#include "asm-common.h" + + .arch .pclmul + + .text + +///-------------------------------------------------------------------------- +/// Common register allocation. + +#if CPUFAM_X86 +# define A eax +# define K edx +#elif CPUFAM_AMD64 && ABI_SYSV +# define A rdi +# define K rsi +#elif CPUFAM_AMD64 && ABI_WIN +# define A rcx +# define K rdx +#endif + +///-------------------------------------------------------------------------- +/// Multiplication macros. + + // The good news is that we have a fancy instruction to do the + // multiplications. The bad news is that it's not particularly well- + // suited to the job. + // + // For one thing, it only does a 64-bit multiplication, so in general + // we'll need to synthesize the full-width multiply by hand. For + // another thing, it doesn't help with the reduction, so we have to + // do that by hand too. And, finally, GCM has crazy bit ordering, + // and the instruction does nothing useful for that at all. + // + // Focusing on that last problem first: the bits aren't in monotonic + // significance order unless we permute them. If we reverse the byte + // order, then we'll have the bits in monotonic order, but backwards, + // so the degree-0 coefficient will be in the most-significant bit. + // + // This is less of a difficulty than it seems at first, because + // algebra. Suppose we are given u = SUM_{0<=i + +#include + +#include "dispatch.h" +#include "gcm.h" +#include "gcm-def.h" + +/*----- Overall strategy --------------------------------------------------* + * + * GCM is pretty awful to implement in software. (This presentation is going + * to be somewhat different to that in the specification, but I think it + * makes more sense like this.) + * + * We're given a %$w$%-bit blockcipher %$E$% with a key %$K$%. + * + * The main part is arithmetic in the finite field %$k = \gf{2^w}$%, which we + * represent as the quotient ring %$\gf{2}[t]/(p_w(t))$% for some irreducible + * degree-%$w$% polynomial %$p(t)$%, whose precise value isn't very important + * right now. We choose a secret point %$x = E_K(0^w)$%. + * + * We choose a length size %$z$% as follows: if %$w < 96%$ then %$z = w$%; + * otherwise %$z = w/2$%. Format a message pair as follows: + * + * %$F(a, b) = P_w(a) \cat P_w(b) \cat [\ell(a)]_z \cat [\ell(b)]_z$% + * + * where %$P_w(x) = x \cat 0^n$% where $%0 \le n < w$% such that + * %$\ell(x) + n \equiv 0 \pmod{w}$%. + * + * Hash a (block-aligned) message %$u$% as follows. First, split %$u$% into + * %$w$%-bit blocks %$u_0$%, %$u_1$%, %%\ldots%%, %$u_{n-1}$%. Interpret + * these as elements of %$k$%. Then + * + * %$G_x(u) = u_0 t^n + u_1 t^{n-1} + \cdots + u_{n-1} t$% + * + * converted back to a %$w$%-bit string. + * + * We're ready to go now. Suppose we're to encrypt a message %$M$% with + * header %$H$% and nonce %$N$%. If %$\ell(N) + 32 = w$% then let + * %$N' = N$% and let %$i_0 = 1$%; otherwise, let %$U = G_t(F(\epsilon, N))$% + * and split this into %$N' = U[0 \bitsto w - 32]$% and + * %$[i_0]_{32} = U[w - 32 \bitsto w]$%. + * + * Let %$n = \lceil \ell(M)/w \rceil$%. Compute + * + * %$y_j = E_K(N' \cat [i_0 + j]_{32})$% + * + * for %$0 \le j \le n$%. Let + * + * %$s = (y_1 \cat y_2 \cat \cdots \cat y_n)[0 \bitsto \ell(M)$% + * + * Let %$C = M \xor s$% and let %$T = G_x(F(H, C)) \xor y_0$%. These are the + * ciphertext and tag respectively. + * + * So why is this awful? + * + * For one thing, the bits are in a completely terrible order. The bytes are + * arranged in little-endian order, so the unit coefficient is in the first + * byte, and the degree-127 coefficient is in the last byte. But within each + * byte, the lowest-degree coefficient is in the most significant bit. It's + * therefore better to think of GCM as using a big-endian byte-ordering + * convention, but with the bits backwards. + * + * But messing about with byte ordering is expensive, so let's not do that in + * the inner loop. But multiplication in %$k$% is not easy either. Some + * kind of precomputed table would be nice, but that will leak secrets + * through the cache. + * + * I choose a particularly simple table: given %$x$%, let %$X[i'] = x t^i$%. + * Then $%$x y = \sum_{0\le in - 1]; m = -(t&1u); c = m&p->poly; + for (i = 0; i < p->n; i++) { t = x[i]; z[i] = (t >> 1) ^ c; c = t << 31; } +} + +/* --- @mul@ --- * + * + * Arguments: @const gcm_params *p@ = pointer to the parameters + * @uint32 *z@ = where to write the result + * @const uint32 *x, *y@ = input field elements + * + * Returns: --- + * + * Use: Multiply the input field elements together, and write the + * product to @z@. It's safe for the operands to overlap. Both + * inputs and the output are in big-endian form, i.e., with the + * lowest-degree coefficients in the most significant bits. + */ + +static void mul(const gcm_params *p, uint32 *z, + const uint32 *x, const uint32 *y) +{ + uint32 m, t, u[GCM_NMAX], v[GCM_NMAX]; + unsigned i, j, k; + + /* We can't do this in-place at all, so use temporary space. Make a copy + * of @x@ in @u@, where we can clobber it, and build the product in @v@. + */ + for (i = 0; i < p->n; i++) { u[i] = x[i]; v[i] = 0; } + + /* Repeatedly multiply @x@ (in @u@) by %$t$%, and add together those + * %$x t^i$% selected by the bits of @y@. This is basically what you get + * by streaming the result of @gcm_mktable@ into @gcm_mulk_...@. + */ + for (i = 0; i < p->n; i++) { + t = y[i]; + for (j = 0; j < 32; j++) { + m = -((t >> 31)&1u); + for (k = 0; k < p->n; k++) v[k] ^= u[k]&m; + mult(p, u, u); t <<= 1; + } + } + + /* Write out the result now that it's ready. */ + for (i = 0; i < p->n; i++) z[i] = v[i]; +} + +/*----- Table-based multiplication ----------------------------------------*/ + +/* --- @gcm_mktable@ --- * + * + * Arguments: @const gcm_params *p@ = pointer to the parameters + * @uint32 *ktab@ = where to write the table; there must be + * space for %$32 n$% $%n$%-word entries, i.e., + * %$32 n^2$% 32-bit words in total, where %$n$% is + * @p->n@, the block size in words + * @const uint32 *k@ = input field element + * + * Returns: --- + * + * Use: Construct a table for use by @gcm_mulk_...@ below, to + * multiply (vaguely) efficiently by @k@. + */ + +static void simple_mktable(const gcm_params *p, + uint32 *ktab, const uint32 *k) +{ + unsigned m = (p->f&GCMF_SWAP ? 0x18 : 0); + unsigned i, j, o = m*p->n; + + /* As described above, the table stores entries %$K[i \xor m] = k t^i$%, + * where %$m = 0$% (big-endian cipher) or %$m = 24$% (little-endian). + * The first job is to store %$K[m] = k$%. + * + * We initially build the table with the entries in big-endian order, and + * then swap them if necessary. This makes the arithmetic functions more + * amenable for use by @gcm_concat@ below. + */ + if (!(p->f&GCMF_SWAP)) for (i = 0; i < p->n; i++) ktab[o + i] = k[i]; + else for (i = 0; i < p->n; i++) ktab[o + i] = ENDSWAP32(k[i]); + + /* Fill in the rest of the table by repeatedly multiplying the previous + * entry by %$t$%. + */ + for (i = 1; i < 32*p->n; i++) + { j = (i ^ m)*p->n; mult(p, ktab + j, ktab + o); o = j; } + + /* Finally, if the cipher uses a little-endian convention, then swap all of + * the individual words. + */ + if (p->f&GCMF_SWAP) + for (i = 0; i < 32*p->n*p->n; i++) ktab[i] = ENDSWAP32(ktab[i]); +} + +#if CPUFAM_X86 || CPUFAM_AMD64 +static void pclmul_mktable(const gcm_params *p, + uint32 *ktab, const uint32 *k) +{ + unsigned n = p->n; + unsigned nz; + uint32 *t; + + /* We just need to store the value in a way which is convenient for the + * assembler code to read back. That involves reordering the words, and, + * in the case of 96-bit blocks, padding with zeroes to fill out a 128-bit + * chunk. + */ + + if (n == 3) nz = 1; + else nz = 0; + t = ktab + n + nz; + + if (p->f&GCMF_SWAP) while (n--) { *--t = ENDSWAP32(*k); k++; } + else while (n--) *--t = *k++; + while (nz--) *--t = 0; +} +#endif + +#if CPUFAM_ARMEL +static void arm_crypto_mktable(const gcm_params *p, + uint32 *ktab, const uint32 *k) +{ + unsigned n = p->n; + uint32 *t; + + /* We just need to store the value in a way which is convenient for the + * assembler code to read back. That involves swapping the bytes in each + * 64-bit lane. + */ + + t = ktab; + if (p->f&GCMF_SWAP) { + while (n >= 2) { + t[1] = ENDSWAP32(k[0]); t[0] = ENDSWAP32(k[1]); + t += 2; k += 2; n -= 2; + } + if (n) { t[1] = ENDSWAP32(k[0]); t[0] = 0; } + } else { + while (n >= 2) { + t[1] = k[0]; t[0] = k[1]; + t += 2; k += 2; n -= 2; + } + if (n) { t[1] = k[0]; t[0] = 0; } + } +} +#endif + +#if CPUFAM_ARM64 +static uint32 rbit32(uint32 x) +{ + uint32 z, t; + +#if GCC_VERSION_P(4, 3) + /* Two tricks here. Firstly, two separate steps, rather than a single + * block of assembler, to allow finer-grained instruction scheduling. + * Secondly, use `ENDSWAP32' so that the compiler can cancel it if the + * caller actually wants the bytes reordered. + */ + __asm__("rbit %w0, %w1" : "=r"(t) : "r"(x)); + z = ENDSWAP32(t); +#else + /* A generic but slightly clever implementation. */ +# define SWIZZLE(x, m, s) ((((x)&(m)) << (s)) | (((x)&~(m)) >> (s))) + /* 76543210 */ + t = SWIZZLE(x, 0x0f0f0f0f, 4); /* 32107654 -- swap nibbles */ + t = SWIZZLE(t, 0x33333333, 2); /* 10325476 -- swap bit pairs */ + z = SWIZZLE(t, 0x55555555, 1); /* 01234567 -- swap adjacent bits */ +# undef SWIZZLE +#endif + return (z); +} + +static void arm64_pmull_mktable(const gcm_params *p, + uint32 *ktab, const uint32 *k) +{ + unsigned n = p->n; + uint32 *t; + + /* We just need to store the value in a way which is convenient for the + * assembler code to read back. That involves two transformations: + * + * * firstly, reversing the order of the bits in each byte; and, + * + * * secondly, storing two copies of each 64-bit chunk. + * + * Note that, in this case, we /want/ the little-endian byte order of GCM, + * so endianness-swapping happens in the big-endian case. + */ + + t = ktab; + if (p->f&GCMF_SWAP) { + while (n >= 2) { + t[0] = t[2] = rbit32(k[0]); + t[1] = t[3] = rbit32(k[1]); + t += 4; k += 2; n -= 2; + } + if (n) { t[0] = t[2] = rbit32(k[0]); t[1] = t[3] = 0; } + } else { + while (n >= 2) { + t[0] = t[2] = ENDSWAP32(rbit32(k[0])); + t[1] = t[3] = ENDSWAP32(rbit32(k[1])); + t += 4; k += 2; n -= 2; + } + if (n) { t[0] = t[2] = ENDSWAP32(rbit32(k[0])); t[1] = t[3] = 0; } + } +} +#endif + +CPU_DISPATCH(EMPTY, EMPTY, void, gcm_mktable, + (const gcm_params *p, uint32 *ktab, const uint32 *k), + (p, ktab, k), + pick_mktable, simple_mktable) + +static gcm_mktable__functype *pick_mktable(void) +{ +#if CPUFAM_X86 || CPUFAM_AMD64 + DISPATCH_PICK_COND(gcm_mktable, pclmul_mktable, + cpu_feature_p(CPUFEAT_X86_SSSE3) && + cpu_feature_p(CPUFEAT_X86_PCLMUL)); +#endif +#if CPUFAM_ARMEL + DISPATCH_PICK_COND(gcm_mktable, arm_crypto_mktable, + cpu_feature_p(CPUFEAT_ARM_PMULL)); +#endif +#if CPUFAM_ARM64 + DISPATCH_PICK_COND(gcm_mktable, arm64_pmull_mktable, + cpu_feature_p(CPUFEAT_ARM_PMULL)); +#endif + DISPATCH_PICK_FALLBACK(gcm_mktable, simple_mktable); +} + +/* --- @recover_k@ --- * + * + * Arguments: @const gcm_params *p@ = pointer to the parameters + * @uint32 *k@ = block-sized vector in which to store %$k$% + * @const uint32 *ktab@ = the table encoding %$k$% + * + * Returns: --- + * + * Use: Recovers %$k$%, the secret from which @ktab@ was by + * @gcm_mktable@, from the table, and stores it in internal + * (big-endian) form in @k@. + */ + +static void simple_recover_k(const gcm_params *p, + uint32 *k, const uint32 *ktab) +{ + unsigned i; + + /* If the blockcipher is big-endian, then the key is simply in the first + * table element, in the right format. If the blockcipher is little-endian + * then it's in element 24, and the bytes need swapping. + */ + + if (!(p->f&GCMF_SWAP)) for (i = 0; i < p->n; i++) k[i] = ktab[i]; + else for (i = 0; i < p->n; i++) k[i] = ENDSWAP32(ktab[24*p->n + i]); +} + +#if CPUFAM_X86 || CPUFAM_AMD64 +static void pclmul_recover_k(const gcm_params *p, + uint32 *k, const uint32 *ktab) +{ + unsigned n = p->n; + unsigned nz; + const uint32 *t; + + /* The representation is already independent of the blockcipher endianness. + * We need to compensate for padding, and reorder the words. + */ + + if (n == 3) nz = 1; else nz = 0; + t = ktab + n + nz; + while (n--) *k++ = *--t; +} +#endif + +#if CPUFAM_ARMEL +static void arm_crypto_recover_k(const gcm_params *p, + uint32 *k, const uint32 *ktab) +{ + unsigned n = p->n; + const uint32 *t; + + /* The representation is already independent of the blockcipher endianness. + * We only need to reorder the words. + */ + + t = ktab; + while (n >= 2) { k[1] = t[0]; k[0] = t[1]; t += 2; k += 2; n -= 2; } + if (n) k[0] = t[1]; +} +#endif + +#if CPUFAM_ARM64 +static void arm64_pmull_recover_k(const gcm_params *p, + uint32 *k, const uint32 *ktab) +{ + unsigned n = p->n; + const uint32 *t; + + /* The representation is already independent of the blockcipher endianness. + * We need to skip the duplicate pieces, and unscramble the bytes. + */ + + t = ktab; + while (n >= 2) { + k[0] = ENDSWAP32(rbit32(t[0])); + k[1] = ENDSWAP32(rbit32(t[1])); + t += 4; k += 2; n -= 2; + } + if (n) k[0] = ENDSWAP32(rbit32(t[0])); +} +#endif + +CPU_DISPATCH(static, EMPTY, void, recover_k, + (const gcm_params *p, uint32 *k, const uint32 *ktab), + (p, k, ktab), + pick_recover_k, simple_recover_k) + +static recover_k__functype *pick_recover_k(void) +{ +#if CPUFAM_X86 || CPUFAM_AMD64 + DISPATCH_PICK_COND(recover_k, pclmul_recover_k, + cpu_feature_p(CPUFEAT_X86_SSSE3) && + cpu_feature_p(CPUFEAT_X86_PCLMUL)); +#endif +#if CPUFAM_ARMEL + DISPATCH_PICK_COND(recover_k, arm_crypto_recover_k, + cpu_feature_p(CPUFEAT_ARM_PMULL)); +#endif +#if CPUFAM_ARM64 + DISPATCH_PICK_COND(recover_k, arm64_pmull_recover_k, + cpu_feature_p(CPUFEAT_ARM_PMULL)); +#endif + DISPATCH_PICK_FALLBACK(recover_k, simple_recover_k); +} + +/* --- @gcm_mulk_N{b,l}@ --- * + * + * Arguments: @uint32 *a@ = accumulator to multiply + * @const uint32 *ktab@ = table constructed by @gcm_mktable@ + * + * Returns: --- + * + * Use: Multiply @a@ by @k@ (implicitly represented in @ktab@), + * updating @a@ in-place. There are separate functions for each + * supported block size and endianness because this is the + * function whose performance actually matters. + */ + +#if CPUFAM_X86 || CPUFAM_AMD64 +# define DECL_MULK_X86ISH(var) extern gcm_mulk_##var##__functype \ + gcm_mulk_##var##_x86ish_pclmul_avx, \ + gcm_mulk_##var##_x86ish_pclmul; +# define PICK_MULK_X86ISH(var) do { \ + DISPATCH_PICK_COND(gcm_mulk_##var, gcm_mulk_##var##_x86ish_pclmul_avx, \ + cpu_feature_p(CPUFEAT_X86_AVX) && \ + cpu_feature_p(CPUFEAT_X86_PCLMUL) && \ + cpu_feature_p(CPUFEAT_X86_SSSE3)); \ + DISPATCH_PICK_COND(gcm_mulk_##var, gcm_mulk_##var##_x86ish_pclmul, \ + cpu_feature_p(CPUFEAT_X86_PCLMUL) && \ + cpu_feature_p(CPUFEAT_X86_SSSE3)); \ +} while (0) +#else +# define DECL_MULK_X86ISH(var) +# define PICK_MULK_X86ISH(var) do ; while (0) +#endif + +#if CPUFAM_ARMEL +# define DECL_MULK_ARM(var) \ + extern gcm_mulk_##var##__functype gcm_mulk_##var##_arm_crypto; +# define PICK_MULK_ARM(var) do { \ + DISPATCH_PICK_COND(gcm_mulk_##var, gcm_mulk_##var##_arm_crypto, \ + cpu_feature_p(CPUFEAT_ARM_PMULL)); \ +} while (0) +#else +# define DECL_MULK_ARM(var) +# define PICK_MULK_ARM(var) do ; while (0) +#endif + +#if CPUFAM_ARM64 +# define DECL_MULK_ARM64(var) \ + extern gcm_mulk_##var##__functype gcm_mulk_##var##_arm64_pmull; +# define PICK_MULK_ARM64(var) do { \ + DISPATCH_PICK_COND(gcm_mulk_##var, gcm_mulk_##var##_arm64_pmull, \ + cpu_feature_p(CPUFEAT_ARM_PMULL)); \ +} while (0) +#else +# define DECL_MULK_ARM64(var) +# define PICK_MULK_ARM64(var) do ; while (0) +#endif + +#define DEF_MULK(nbits) \ + \ +CPU_DISPATCH(EMPTY, EMPTY, void, gcm_mulk_##nbits##b, \ + (uint32 *a, const uint32 *ktab), (a, ktab), \ + pick_mulk_##nbits##b, simple_mulk_##nbits) \ +CPU_DISPATCH(EMPTY, EMPTY, void, gcm_mulk_##nbits##l, \ + (uint32 *a, const uint32 *ktab), (a, ktab), \ + pick_mulk_##nbits##l, simple_mulk_##nbits) \ + \ +static void simple_mulk_##nbits(uint32 *a, const uint32 *ktab) \ +{ \ + uint32 m, t; \ + uint32 z[nbits/32]; \ + unsigned i, j, k; \ + \ + for (i = 0; i < nbits/32; i++) z[i] = 0; \ + \ + for (i = 0; i < nbits/32; i++) { \ + t = a[i]; \ + for (j = 0; j < 32; j++) { \ + m = -((t >> 31)&1u); \ + for (k = 0; k < nbits/32; k++) z[k] ^= *ktab++&m; \ + t <<= 1; \ + } \ + } \ + \ + for (i = 0; i < nbits/32; i++) a[i] = z[i]; \ +} \ + \ +DECL_MULK_X86ISH(nbits##b) \ +DECL_MULK_ARM(nbits##b) \ +DECL_MULK_ARM64(nbits##b) \ +static gcm_mulk_##nbits##b##__functype *pick_mulk_##nbits##b(void) \ +{ \ + PICK_MULK_X86ISH(nbits##b); \ + PICK_MULK_ARM(nbits##b); \ + PICK_MULK_ARM64(nbits##b); \ + DISPATCH_PICK_FALLBACK(gcm_mulk_##nbits##b, simple_mulk_##nbits); \ +} \ + \ +DECL_MULK_X86ISH(nbits##l) \ +DECL_MULK_ARM(nbits##l) \ +DECL_MULK_ARM64(nbits##l) \ +static gcm_mulk_##nbits##l##__functype *pick_mulk_##nbits##l(void) \ +{ \ + PICK_MULK_X86ISH(nbits##l); \ + PICK_MULK_ARM(nbits##l); \ + PICK_MULK_ARM64(nbits##l); \ + DISPATCH_PICK_FALLBACK(gcm_mulk_##nbits##l, simple_mulk_##nbits); \ +} + +GCM_WIDTHS(DEF_MULK) + +#define GCM_MULK_CASE(nbits) \ + case nbits/32: \ + if (_f&GCMF_SWAP) gcm_mulk_##nbits##l(_a, _ktab); \ + else gcm_mulk_##nbits##b(_a, _ktab); \ + break; +#define MULK(n, f, a, ktab) do { \ + uint32 *_a = (a); const uint32 *_ktab = (ktab); \ + unsigned _f = (f); \ + switch (n) { \ + GCM_WIDTHS(GCM_MULK_CASE) \ + default: abort(); \ + } \ +} while (0) + +/*----- Other utilities ---------------------------------------------------*/ + +/* --- @putlen@ --- * + * + * Arguments: @octet *p@ = pointer to output buffer + * @unsigned w@ = size of output buffer + * @unsigned blksz@ = block size (assumed fairly small) + * @unsigned long nblocks@ = number of blocks + * @unsigned nbytes@ = tail size in bytes (assumed small) + * + * Returns: --- + * + * Use: Store the overall length in %$\emph{bits}$% (i.e., + * @3*(nblocks*blksz + nbytes)@ in big-endian form in the + * buffer @p@. + */ + +static void putlen(octet *p, unsigned w, unsigned blksz, + unsigned long nblocks, unsigned nbytes) +{ + unsigned long nblo = nblocks&((1ul << (ULONG_BITS/2)) - 1), + nbhi = nblocks >> ULONG_BITS/2; + unsigned long nlo = nblo*blksz + nbytes, nhi = nbhi*blksz; + + /* This is fiddly. Split @nblocks@, which is the big number, into high and + * low halves, multiply those separately by @blksz@, propagate carries, and + * then multiply by eight. + */ + nhi += nlo >> ULONG_BITS/2; + nlo &= (1ul << (ULONG_BITS/2)) - 1; + nlo <<= 3; + + /* Now write out the size, feeding bits in from @nhi@ as necessary. */ + p += w; + while (w--) { + *--p = U8(nlo); + nlo = (nlo >> 8) | ((nhi&0xff) << (ULONG_BITS/2 - 5)); + nhi >>= 8; + } +} + +/* --- @mix@ --- * + * + * Arguments: @const gcm_params *p@ = pointer to the parameters + * @uint32 *a@ = GHASH accumulator + * @const octet *q@ = pointer to an input block + * @const uint32 *ktab@ = multiplication table, built by + * @gcm_mktable@ + * + * Returns: --- + * + * Use: Fold the block @q@ into the GHASH accumulator. The + * calculation is %$a' = k (a + q)$%. + */ + +static void mix(const gcm_params *p, uint32 *a, + const octet *q, const uint32 *ktab) +{ + unsigned i; + + if (p->f&GCMF_SWAP) + for (i = 0; i < p->n; i++) { a[i] ^= LOAD32_L(q); q += 4; } + else + for (i = 0; i < p->n; i++) { a[i] ^= LOAD32_B(q); q += 4; } + MULK(p->n, p->f, a, ktab); +} + +/* --- @gcm_ghashdone@ --- * + * + * Arguments: @const gcm_params *p@ = pointer to the parameters + * @uint32 *a@ = GHASH accumulator + * @const uint32 *ktab@ = multiplication table, built by + * @gcm_mktable@ + * @unsigned long xblocks, yblocks@ = number of whole blocks in + * the two inputs + * @unsigned xbytes, ybytes@ = number of trailing bytes in the + * two inputs + * + * Returns: --- + * + * Use: Finishes a GHASH operation by appending the appropriately + * encoded lengths of the two constituent messages. + */ + +void gcm_ghashdone(const gcm_params *p, uint32 *a, const uint32 *ktab, + unsigned long xblocks, unsigned xbytes, + unsigned long yblocks, unsigned ybytes) +{ + octet b[4*GCM_NMAX]; + unsigned w = p->n < 3 ? 4*p->n : 2*p->n; + + /* Construct the encoded lengths. Note that smaller-block versions of GCM + * encode the lengths in separate blocks. GCM is only officially defined + * for 64- and 128-bit blocks; I've placed the cutoff somewhat arbitrarily + * at 96 bits. + */ + putlen(b, w, 4*p->n, xblocks, xbytes); + putlen(b + w, w, 4*p->n, yblocks, ybytes); + + /* Feed the lengths into the accumulator. */ + mix(p, a, b, ktab); + if (p->n < 3) mix(p, a, b + w, ktab); +} + +/* --- @gcm_concat@ --- * + * + * Arguments: @const gcm_params *p@ = pointer to the parameters + * @uint32 *z@ = GHASH accumulator for suffix, updated + * @const uint32 *x@ = GHASH accumulator for prefix + * @const uint32 *ktab@ = multiplication table, built by + * @gcm_mktable@ + * @unsigned long n@ = length of suffix in whole blocks + * + * Returns: --- + * + * Use: On entry, @x@ and @z@ are the results of hashing two strings + * %$a$% and %$b$%, each a whole number of blocks long; in + * particular, %$b$% is @n@ blocks long. On exit, @z@ is + * updated to be the hash of %$a \cat b$%. + */ + +void gcm_concat(const gcm_params *p, uint32 *z, const uint32 *x, + const uint32 *ktab, unsigned long n) +{ + uint32 t[GCM_NMAX], u[GCM_NMAX]; + unsigned i, j; + + if (!n) { + /* If @n@ is zero, then there's not much to do. The mathematics + * (explained below) still works, but the code takes a shortcut which + * doesn't handle this case: so set %$z' = z + x k^n = z + x$%. + */ + + for (j = 0; j < p->n; j++) z[j] ^= x[j]; + } else { + /* We have %$x = a_0 t^m + \cdots + a_{m-2} t^2 + a_{m-1} t$% and + * %$z = b_0 t^n + \cdots + b_{n-2} t^2 + b_{n-1} t$%. What we'd like is + * the hash of %$a \cat b$%, which is %$z + x k^n$%. + * + * The first job, then, is to calculate %$k^n$%, and for this we use a + * simple left-to-right square-and-multiply algorithm. There's no need + * to keep %$n$% secret here. + */ + + /* Start by retrieving %$k$% from the table, and convert it to big-endian + * form. + */ + recover_k(p, u, ktab); + + /* Now calculate %$k^n$%. */ + i = ULONG_BITS; +#define BIT (1ul << (ULONG_BITS - 1)) + while (!(n&BIT)) { n <<= 1; i--; } + n <<= 1; i--; for (j = 0; j < p->n; j++) t[j] = u[j]; + while (i--) { mul(p, t, t, t); if (n&BIT) mul(p, t, t, u); n <<= 1; } +#undef BIT + + /* Next, calculate %$x k^n$%. If we're using a little-endian convention + * then we must convert %$x$%; otherwise we can just use it in place. + */ + if (!(p->f&GCMF_SWAP)) + mul(p, t, t, x); + else { + for (j = 0; j < p->n; j++) u[j] = ENDSWAP32(x[j]); + mul(p, t, t, u); + } + + /* Finally, add %$x k^n$% onto %$z$%, converting back to little-endian if + * necessary. + */ + if (!(p->f&GCMF_SWAP)) for (j = 0; j < p->n; j++) z[j] ^= t[j]; + else for (j = 0; j < p->n; j++) z[j] ^= ENDSWAP32(t[j]); + } +} + +/*----- Test rig ----------------------------------------------------------*/ + +#ifdef TEST_RIG + +#include +#include + +static void report_failure(const char *test, unsigned nbits, + const char *ref, dstr v[], dstr *d) +{ + printf("test %s failed (nbits = %u)", test, nbits); + printf("\n\tx = "); type_hex.dump(&v[0], stdout); + printf("\n\ty = "); type_hex.dump(&v[1], stdout); + printf("\n\tz = "); type_hex.dump(&v[2], stdout); + printf("\n\t%s' = ", ref); type_hex.dump(d, stdout); + putchar('\n'); +} + +static void mulk(unsigned nbits, unsigned f, uint32 *x, const uint32 *ktab) + { MULK(nbits/32, f, x, ktab); } + +static int test_mul(uint32 poly, dstr v[]) +{ + uint32 x[GCM_NMAX], y[GCM_NMAX], z[GCM_NMAX], ktab[32*GCM_NMAX*GCM_NMAX]; + gcm_params p; + dstr d = DSTR_INIT; + unsigned i, nbits; + int ok = 1; + enum { I_x, I_y, I_z }; + + nbits = 8*v[0].len; p.f = 0; p.n = nbits/32; p.poly = poly; + dstr_ensure(&d, nbits/8); d.len = nbits/8; + +#define LOADXY(E) do { \ + for (i = 0; i < nbits/32; i++) { \ + x[i] = LOAD32_##E(v[I_x].buf + 4*i); \ + y[i] = LOAD32_##E(v[I_y].buf + 4*i); \ + } \ +} while (0) + +#define INITZ(x) do { \ + for (i = 0; i < nbits/32; i++) z[i] = (x)[i]; \ +} while (0) + +#define CHECK(E, what, ref) do { \ + for (i = 0; i < nbits/32; i++) STORE32_##E(d.buf + 4*i, z[i]); \ + if (memcmp(d.buf, v[I_##ref].buf, nbits/8) != 0) \ + { ok = 0; report_failure(what, nbits, #ref, v, &d); } \ +} while (0) + +#define TEST_PREP_1(E, x, y, what) do { \ + gcm_mktable(&p, ktab, y); \ + recover_k(&p, z, ktab); CHECK(B, "mktable/recover_k (" #y ")", y); \ + INITZ(x); mulk(nbits, p.f, z, ktab); CHECK(E, what " (k = " #y ")", z); \ +} while (0) + +#define TEST_PREP(E, what) do { \ + TEST_PREP_1(E, x, y, what); \ + TEST_PREP_1(E, y, x, what); \ +} while (0) + + /* First, test plain multiply. */ + LOADXY(B); mul(&p, z, x, y); CHECK(B, "gcm_mul", z); + + /* Next, test big-endian prepared key. */ + LOADXY(B); TEST_PREP(B, "gcm_kmul_b"); + + /* Finally, test little-endian prepared key. */ + p.f = GCMF_SWAP; LOADXY(L); + TEST_PREP(L, "gcm_kmul_l"); + +#undef LOADXY +#undef INITZ +#undef CHECK +#undef TEST_PREP_1 +#undef TEST_PREP + + /* All done. */ + return (ok); +} + +#define TEST(nbits) \ +static int test_mul_##nbits(dstr v[]) \ + { return (test_mul(GCM_POLY_##nbits, v)); } +GCM_WIDTHS(TEST) +#undef TEST + +static test_chunk defs[] = { +#define TEST(nbits) \ + { "gcm-mul" #nbits, test_mul_##nbits, \ + { &type_hex, &type_hex, &type_hex, 0 } }, +GCM_WIDTHS(TEST) +#undef TEST + { 0, 0, { 0 } } +}; + +int main(int argc, char *argv[]) +{ + ego(argv[0]); + test_run(argc, argv, defs, SRCDIR"/t/gcm"); + return (0); +} + +#endif + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/symm/gcm.h b/symm/gcm.h new file mode 100644 index 00000000..d3e6d030 --- /dev/null +++ b/symm/gcm.h @@ -0,0 +1,308 @@ +/* -*-c-*- + * + * The GCM authenticated encryption mode + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Notes on GCM ------------------------------------------------------* + * + * The name is short for `Galois Counter Mode'. GCM was designed in 2005 by + * David McGrew and John Viega as a fast, patent-free authenticated + * encryption scheme; and it's specified by NIST in SP800-38D. It combines + * counter-mode encryption with a Carter--Wegman authenticator based on a + * polynomial hash over %$\gf{2^{128}}%, so it needs only one blockcipher + * application per message block, together with a multiplication by a + * constant in the finite field. GCM is essentially the winner in the + * authenticated-encryption-mode competition, to the extent that Intel and + * ARM both added instructions to their architectures to accelerate it. + * + * GCM allows arbitrary-sized nonces, though it's happiest if the nonce is 32 + * bits shorter than the block size, leaving a fixed-size block counter in + * the low 32 bits. It permits header data to be processed independently of + * the message, though doing this requires some slightly fiddly algebra and + * most implementations don't allow callers to take advantage of this. + * + * One downside is that the field multiplication is inefficient in software. + * Back in 2005 it was assumed that implementors would use large tables, but + * that leaks the authentication secret through the processor cache. This + * implementation runs in constant time, but the penalty is that, without + * dedicated processor support, it's much slower than an extra blockcipher + * application would have been. + * + * Another downside is that, while GCM came with a security proof, it was + * subtly incorrect in a few ways which mean that its concrete security is + * significantly less than one would expect. + * + * If interoperability isn't a concern, then OCB3 is probably a better + * choice; if the OCB patent situation is also worrying, then EAX is likely + * preferable. + */ + +#ifndef CATACOMB_GCM_H +#define CATACOMB_GCM_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +#ifndef CATACOMB_GAEAD_H +# include "gaead.h" +#endif + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @GCM_DECL@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates declarations for GCM authenticated-encryption mode. + */ + +#define GCM_DECL(PRE, pre) \ + \ +typedef struct pre##_gcmkey { \ + pre##_ctx ctx; /* Block cipher key */ \ + uint32 ktab[32*PRE##_BLKSZ*PRE##_BLKSZ]; /* Multiplication table */ \ +} pre##_gcmkey; \ + \ +typedef struct pre##_gcmaadctx { \ + pre##_gcmkey k; /* Underlying key */ \ + uint32 a[PRE##_BLKSZ/4]; /* GHASH accumulator */ \ + octet b[PRE##_BLKSZ]; /* Input buffer */ \ + unsigned off; /* Length of stuff in buffer */ \ + unsigned long len; /* Number of blocks so far */ \ +} pre##_gcmaadctx; \ + \ +typedef struct pre##_gcmctx { \ + /* The buffer is split into two portions. The first N octets hold a \ + * chunk of ciphertext, which will be fed into the OMAC calculation; \ + * the remaining BLKSZ - N octets hold E_K(C), which is the XOR mask \ + * to apply to the plaintext or ciphertext. \ + */ \ + pre##_gcmkey k; /* Underlying key */ \ + uint32 c[PRE##_BLKSZ/4]; /* Current counter value */ \ + uint32 c0[PRE##_BLKSZ/4]; /* Initial counter */ \ + uint32 a[PRE##_BLKSZ]; /* GHASH accumulator */ \ + octet b[PRE##_BLKSZ]; /* Ciphertext/mask buffer */ \ + unsigned off; /* Crossover point in buffer */ \ + unsigned long len; /* Number of blocks so far */ \ +} pre##_gcmctx; \ + \ +extern const octet pre##_gcmnoncesz[], pre##_gcmtagsz[]; \ + \ +/* --- @pre_gcmsetkey@ --- * \ + * \ + * Arguments: @pre_gcmkey *key@ = pointer to key block to fill in \ + * @const void *k@ = pointer to key material \ + * @size_t ksz@ = size of key material \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an GCM key block. \ + */ \ + \ +extern void pre##_gcmsetkey(pre##_gcmkey */*key*/, \ + const void */*k*/, size_t /*ksz*/); \ + \ +/* --- @pre_gcmaadinit@ --- * \ + * \ + * Arguments: @pre_gcmaadctx *aad@ = pointer to AAD context \ + * @const pre_gcmkey *key@ = pointer to key block \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an GCM AAD (`additional authenticated \ + * data') context associated with a given key. AAD \ + * contexts can be copied and/or reused, saving time if \ + * the AAD for a number of messages has a common prefix. \ + * \ + * The @key@ doesn't need to be kept around, though \ + * usually there'll at least be another copy in some GCM \ + * operation context because the AAD on its own isn't much \ + * good. \ + */ \ + \ +extern void pre##_gcmaadinit(pre##_gcmaadctx */*aad*/, \ + const pre##_gcmkey */*key*/); \ + \ +/* --- @pre_gcmaadhash@ --- * \ + * \ + * Arguments: @pre_gcmaadctx *aad@ = pointer to AAD context \ + * @const void *p@ = pointer to AAD material \ + * @size_t sz@ = length of AAD material \ + * \ + * Returns: --- \ + * \ + * Use: Feeds AAD into the context. \ + */ \ + \ +extern void pre##_gcmaadhash(pre##_gcmaadctx */*aad*/, \ + const void */*p*/, size_t /*sz*/); \ + \ +/* --- @pre_gcminit@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to GCM context \ + * @const pre_gcmkey *key@ = pointer to key block \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: --- \ + * \ + * Use: Initialize an GCM operation context with a given key. \ + * \ + * The original key needn't be kept around any more. \ + */ \ + \ +extern void pre##_gcminit(pre##_gcmctx */*ctx*/, \ + const pre##_gcmkey */*k*/, \ + const void */*n*/, size_t /*nsz*/); \ + \ +/* --- @pre_gcmreinit@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to GCM context \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: --- \ + * \ + * Use: Reinitialize an GCM operation context, changing the \ + * nonce. \ + */ \ + \ +extern void pre##_gcmreinit(pre##_gcmctx */*ctx*/, \ + const void */*n*/, size_t /*nsz*/); \ + \ +/* --- @pre_gcmencrypt@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to GCM operation context \ + * @const void *src@ = pointer to plaintext message chunk \ + * @size_t sz@ = size of the plaintext \ + * @buf *dst@ = a buffer to write the ciphertext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Encrypts a chunk of a plaintext message, writing a \ + * chunk of ciphertext to the output buffer and updating \ + * the operation state. \ + * \ + * For GCM, we always write a ciphertext chunk the same \ + * size as the plaintext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +extern int pre##_gcmencrypt(pre##_gcmctx */*ctx*/, \ + const void */*src*/, size_t /*sz*/, \ + buf */*dst*/); \ + \ +/* --- @pre_gcmdecrypt@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to GCM operation context \ + * @const void *src@ = pointer to ciphertext message chunk \ + * @size_t sz@ = size of the ciphertext \ + * @buf *dst@ = a buffer to write the plaintext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Decrypts a chunk of a ciphertext message, writing a \ + * chunk of plaintext to the output buffer and updating \ + * the operation state. \ + * \ + * For GCM, we always write a plaintext chunk the same \ + * size as the ciphertext. The messing about with @buf@ \ + * objects makes the interface consistent with other AEAD \ + * schemes which can't do this. \ + */ \ + \ +extern int pre##_gcmdecrypt(pre##_gcmctx */*ctx*/, \ + const void */*src*/, size_t /*sz*/, \ + buf */*dst*/); \ + \ +/* --- @pre_gcmencryptdone@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to an GCM context \ + * @const pre_gcmaadctx *aad@ = pointer to AAD context, or \ + * null \ + * @buf *dst@ = buffer for remaining ciphertext \ + * @void *tag@ = where to write the tag \ + * @size_t tsz@ = length of tag to store \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Completes an GCM encryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. GCM doesn't buffer ciphertext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +extern int pre##_gcmencryptdone(pre##_gcmctx */*ctx*/, \ + const pre##_gcmaadctx */*aad*/, \ + buf */*dst*/, \ + void */*tag*/, size_t /*tsz*/); \ + \ +/* --- @pre_gcmdecryptdone@ --- * \ + * \ + * Arguments: @pre_gcmctx *ctx@ = pointer to an GCM context \ + * @const pre_gcmaadctx *aad@ = pointer to AAD context, or \ + * null \ + * @buf *dst@ = buffer for remaining plaintext \ + * @const void *tag@ = tag to verify \ + * @size_t tsz@ = length of tag \ + * \ + * Returns: @+1@ for complete success; @0@ if tag verification \ + * failed; @-1@ for other kinds of errors. \ + * \ + * Use: Completes an GCM decryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. GCM doesn't buffer plaintext, but \ + * the output buffer is provided anyway for consistency \ + * with other AEAD schemes which don't have this property; \ + * the function will fail if the output buffer is broken. \ + */ \ + \ +extern int pre##_gcmdecryptdone(pre##_gcmctx */*ctx*/, \ + const pre##_gcmaadctx */*aad*/, \ + buf */*dst*/, \ + const void */*tag*/, size_t /*tsz*/); \ + \ +/* --- Generic AEAD interface --- */ \ + \ +extern const gcaead pre##_gcm; + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/hash.h b/symm/hash.h index eb3cd75e..3d0c1179 100644 --- a/symm/hash.h +++ b/symm/hash.h @@ -38,6 +38,10 @@ #include +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + /*----- Macros ------------------------------------------------------------*/ /* --- @HASH_BUFFER@ --- * @@ -58,7 +62,10 @@ #define HASH_BUFFER(PRE, pre, ictx, ibuf, isz) do { \ pre##_ctx *_bctx = (ictx); \ size_t _bsz = (isz); \ - const octet *_bbuf = (octet *)(ibuf); \ + const octet *_bbuf = (octet *)(ibuf), *_p; \ + static const rsvr_policy _pol = { 0, PRE##_BUFSZ, PRE##_BUFSZ }; \ + uint32 _l, _h; \ + rsvr_state _st; \ \ /* --- Add on the size done so far --- * \ * \ @@ -66,44 +73,15 @@ * how many bits you've actually got. \ */ \ \ - { \ - uint32 _l = U32(_bsz); \ - uint32 _h = ((_bsz & ~(size_t)MASK32) >> 16) >> 16; \ - _bctx->nh += _h; \ - _bctx->nl += _l; \ - if (_bctx->nl < _l || _bctx->nl & ~(uint32)MASK32) \ - _bctx->nh++; \ - } \ - \ - /* --- Handle very small contributions --- */ \ - \ - if (_bctx->off + _bsz < PRE##_BUFSZ) { \ - memcpy(_bctx->buf + _bctx->off, _bbuf, _bsz); \ - _bctx->off += _bsz; \ - } else { \ - \ - /* --- Handle an initial partial buffer --- */ \ + _l = U32(_bsz); _h = ((_bsz & ~(size_t)MASK32) >> 16) >> 16; \ + _bctx->nl += _l; if (_bctx->nl < _l || _bctx->nl & ~(uint32)MASK32) _h++; \ + _bctx->nh += _h; \ \ - if (_bctx->off) { \ - size_t s = PRE##_BUFSZ - _bctx->off; \ - memcpy(_bctx->buf + _bctx->off, _bbuf, s); \ - pre##_compress(_bctx, _bctx->buf); \ - _bsz -= s; _bbuf += s; \ - } \ - \ - /* --- Do whole buffers while we can --- */ \ - \ - while (_bsz >= PRE##_BUFSZ) { \ - pre##_compress(_bctx, _bbuf); \ - _bsz -= PRE##_BUFSZ; _bbuf += PRE##_BUFSZ; \ - } \ - \ - /* --- And wrap up at the end --- */ \ + /* --- Accumulate the input data --- */ \ \ - if (_bsz) \ - memcpy(_bctx->buf, _bbuf, _bsz); \ - _bctx->off = _bsz; \ - } \ + rsvr_setup(&_st, &_pol, _bctx->buf, &_bctx->off, _bbuf, _bsz); \ + RSVR_DO(&_st) while ((_p = RSVR_NEXT(&_st, PRE##_BUFSZ)) != 0) \ + pre##_compress(_bctx, _p); \ } while (0) /* --- @HASH_PAD@ --- * diff --git a/symm/hmac-def.h b/symm/hmac-def.h index 72bd126a..e3f12ced 100644 --- a/symm/hmac-def.h +++ b/symm/hmac-def.h @@ -208,9 +208,7 @@ void pre##_macinit(pre##_macctx *ctx, const pre##_mackey *key) \ */ \ \ void pre##_machash(pre##_macctx *ctx, const void *buf, size_t sz) \ -{ \ - pre##_hash(&ctx->ctx, buf, sz); \ -} \ + { pre##_hash(&ctx->ctx, buf, sz); } \ \ /* --- @pre_macdone@ --- * \ * \ diff --git a/symm/keccak1600.c b/symm/keccak1600.c index 10a3516a..d58bc6f8 100644 --- a/symm/keccak1600.c +++ b/symm/keccak1600.c @@ -338,25 +338,25 @@ static void keccak1600_round(keccak1600_state *z, * result to Z. */ - lane b[5], c[5], d[5], t; + lane c[5], d[5], t; /* Theta, first step: calculate the column parities. */ #define COLPARITY(j) do { \ - c[j] = x->S[I(j, 0)]; \ - XOR_LANE(c[j], c[j], x->S[I(j, 1)]); \ - XOR_LANE(c[j], c[j], x->S[I(j, 2)]); \ - XOR_LANE(c[j], c[j], x->S[I(j, 3)]); \ - XOR_LANE(c[j], c[j], x->S[I(j, 4)]); \ + d[j] = x->S[I(j, 0)]; \ + XOR_LANE(d[j], d[j], x->S[I(j, 1)]); \ + XOR_LANE(d[j], d[j], x->S[I(j, 2)]); \ + XOR_LANE(d[j], d[j], x->S[I(j, 3)]); \ + XOR_LANE(d[j], d[j], x->S[I(j, 4)]); \ } while (0) COLPARITY(0); COLPARITY(1); COLPARITY(2); COLPARITY(3); COLPARITY(4); #undef COLPARITY /* Theta, second step: calculate the combined effect. */ - ROTL_LANE(d[0], c[1], 1); XOR_LANE(d[0], d[0], c[4]); - ROTL_LANE(d[1], c[2], 1); XOR_LANE(d[1], d[1], c[0]); - ROTL_LANE(d[2], c[3], 1); XOR_LANE(d[2], d[2], c[1]); - ROTL_LANE(d[3], c[4], 1); XOR_LANE(d[3], d[3], c[2]); - ROTL_LANE(d[4], c[0], 1); XOR_LANE(d[4], d[4], c[3]); + ROTL_LANE(c[0], d[1], 1); XOR_LANE(c[0], c[0], d[4]); + ROTL_LANE(c[1], d[2], 1); XOR_LANE(c[1], c[1], d[0]); + ROTL_LANE(c[2], d[3], 1); XOR_LANE(c[2], c[2], d[1]); + ROTL_LANE(c[3], d[4], 1); XOR_LANE(c[3], c[3], d[2]); + ROTL_LANE(c[4], d[0], 1); XOR_LANE(c[4], c[4], d[3]); /* Now we work plane by plane through the output. To do this, we must undo * the pi transposition. Pi maps (x', y') = (y, 2 x + 3 y), so y = x', and @@ -365,18 +365,18 @@ static void keccak1600_round(keccak1600_state *z, #define THETA_RHO(i0, i1, i2, i3, i4) do { \ \ /* First, theta. */ \ - XOR_LANE(b[0], x->S[I(i0, 0)], d[i0]); \ - XOR_LANE(b[1], x->S[I(i1, 1)], d[i1]); \ - XOR_LANE(b[2], x->S[I(i2, 2)], d[i2]); \ - XOR_LANE(b[3], x->S[I(i3, 3)], d[i3]); \ - XOR_LANE(b[4], x->S[I(i4, 4)], d[i4]); \ + XOR_LANE(d[0], x->S[I(i0, 0)], c[i0]); \ + XOR_LANE(d[1], x->S[I(i1, 1)], c[i1]); \ + XOR_LANE(d[2], x->S[I(i2, 2)], c[i2]); \ + XOR_LANE(d[3], x->S[I(i3, 3)], c[i3]); \ + XOR_LANE(d[4], x->S[I(i4, 4)], c[i4]); \ \ /* Then rho. */ \ - ROTL_LANE(b[0], b[0], ROT_##i0##_0); \ - ROTL_LANE(b[1], b[1], ROT_##i1##_1); \ - ROTL_LANE(b[2], b[2], ROT_##i2##_2); \ - ROTL_LANE(b[3], b[3], ROT_##i3##_3); \ - ROTL_LANE(b[4], b[4], ROT_##i4##_4); \ + ROTL_LANE(d[0], d[0], ROT_##i0##_0); \ + ROTL_LANE(d[1], d[1], ROT_##i1##_1); \ + ROTL_LANE(d[2], d[2], ROT_##i2##_2); \ + ROTL_LANE(d[3], d[3], ROT_##i3##_3); \ + ROTL_LANE(d[4], d[4], ROT_##i4##_4); \ } while (0) /* The basic chi operation is: z = w ^ (~a&b), but this involves an @@ -435,55 +435,55 @@ static void keccak1600_round(keccak1600_state *z, * This is hairy because we must worry about complementation. */ THETA_RHO(0, 1, 2, 3, 4); - CHI_COMPL(t, b[2]); /* [.] */ - CHI_101_0(z->S[I(0, 0)], b[0], b[1], b[2]); /* * . * -> . */ - CHI_001_1(z->S[I(1, 0)], b[1], t, b[3]); /* . [.] * -> * */ - CHI_110_1(z->S[I(2, 0)], b[2], b[3], b[4]); /* * * . -> * */ - CHI_101_0(z->S[I(3, 0)], b[3], b[4], b[0]); /* * * . -> . */ - CHI_010_0(z->S[I(4, 0)], b[4], b[0], b[1]); /* * . . -> . */ + CHI_COMPL(t, d[2]); /* [.] */ + CHI_101_0(z->S[I(0, 0)], d[0], d[1], d[2]); /* * . * -> . */ + CHI_001_1(z->S[I(1, 0)], d[1], t, d[3]); /* . [.] * -> * */ + CHI_110_1(z->S[I(2, 0)], d[2], d[3], d[4]); /* * * . -> * */ + CHI_101_0(z->S[I(3, 0)], d[3], d[4], d[0]); /* * * . -> . */ + CHI_010_0(z->S[I(4, 0)], d[4], d[0], d[1]); /* * . . -> . */ /* We'd better do iota before we forget. */ XOR_LANE(z->S[I(0, 0)], z->S[I(0, 0)], rcon[i]); /* That was fun. Maybe y' = 1 will be as good. */ THETA_RHO(3, 4, 0, 1, 2); - CHI_COMPL(t, b[4]); /* [*] */ - CHI_101_0(z->S[I(0, 1)], b[0], b[1], b[2]); /* * . * -> . */ - CHI_010_0(z->S[I(1, 1)], b[1], b[2], b[3]); /* . * . -> . */ - CHI_101_0(z->S[I(2, 1)], b[2], b[3], t); /* * . [*] -> . */ - CHI_001_1(z->S[I(3, 1)], b[3], b[4], b[0]); /* * . . -> * */ - CHI_010_0(z->S[I(4, 1)], b[4], b[0], b[1]); /* * . . -> . */ + CHI_COMPL(t, d[4]); /* [*] */ + CHI_101_0(z->S[I(0, 1)], d[0], d[1], d[2]); /* * . * -> . */ + CHI_010_0(z->S[I(1, 1)], d[1], d[2], d[3]); /* . * . -> . */ + CHI_101_0(z->S[I(2, 1)], d[2], d[3], t); /* * . [*] -> . */ + CHI_001_1(z->S[I(3, 1)], d[3], d[4], d[0]); /* * . . -> * */ + CHI_010_0(z->S[I(4, 1)], d[4], d[0], d[1]); /* * . . -> . */ /* We're getting the hang of this. The y' = 2 plane shouldn't be any * trouble. */ THETA_RHO(1, 2, 3, 4, 0); - CHI_COMPL(t, b[3]); /* [*] */ - CHI_101_0(z->S[I(0, 2)], b[0], b[1], b[2]); /* * . * -> . */ - CHI_010_0(z->S[I(1, 2)], b[1], b[2], b[3]); /* . * . -> . */ - CHI_110_1(z->S[I(2, 2)], b[2], t, b[4]); /* * [*] . -> * */ - CHI_101_0(z->S[I(3, 2)], t, b[4], b[0]); /* * [*] . -> . */ - CHI_010_0(z->S[I(4, 2)], b[4], b[0], b[1]); /* * . . -> . */ + CHI_COMPL(t, d[3]); /* [*] */ + CHI_101_0(z->S[I(0, 2)], d[0], d[1], d[2]); /* * . * -> . */ + CHI_010_0(z->S[I(1, 2)], d[1], d[2], d[3]); /* . * . -> . */ + CHI_110_1(z->S[I(2, 2)], d[2], t, d[4]); /* * [*] . -> * */ + CHI_101_0(z->S[I(3, 2)], t, d[4], d[0]); /* * [*] . -> . */ + CHI_010_0(z->S[I(4, 2)], d[4], d[0], d[1]); /* * . . -> . */ /* This isn't as interesting any more. Let's do y' = 3 before boredom sets * in. */ THETA_RHO(4, 0, 1, 2, 3); - CHI_COMPL(t, b[3]); /* [.] */ - CHI_010_0(z->S[I(0, 3)], b[0], b[1], b[2]); /* . * . -> . */ - CHI_101_0(z->S[I(1, 3)], b[1], b[2], b[3]); /* * . * -> . */ - CHI_001_1(z->S[I(2, 3)], b[2], t, b[4]); /* . [.] * -> * */ - CHI_010_0(z->S[I(3, 3)], t, b[4], b[0]); /* . [.] * -> . */ - CHI_101_0(z->S[I(4, 3)], b[4], b[0], b[1]); /* . * * -> . */ + CHI_COMPL(t, d[3]); /* [.] */ + CHI_010_0(z->S[I(0, 3)], d[0], d[1], d[2]); /* . * . -> . */ + CHI_101_0(z->S[I(1, 3)], d[1], d[2], d[3]); /* * . * -> . */ + CHI_001_1(z->S[I(2, 3)], d[2], t, d[4]); /* . [.] * -> * */ + CHI_010_0(z->S[I(3, 3)], t, d[4], d[0]); /* . [.] * -> . */ + CHI_101_0(z->S[I(4, 3)], d[4], d[0], d[1]); /* . * * -> . */ /* Last plane. Just y' = 4 to go. */ THETA_RHO(2, 3, 4, 0, 1); - CHI_COMPL(t, b[1]); /* [*] */ - CHI_110_1(z->S[I(0, 4)], b[0], t, b[2]); /* * [*] . -> * */ - CHI_101_0(z->S[I(1, 4)], t, b[2], b[3]); /* [*] . * -> . */ - CHI_010_0(z->S[I(2, 4)], b[2], b[3], b[4]); /* . * . -> . */ - CHI_101_0(z->S[I(3, 4)], b[3], b[4], b[0]); /* * * . -> . */ - CHI_010_0(z->S[I(4, 4)], b[4], b[0], b[1]); /* * . . -> . */ + CHI_COMPL(t, d[1]); /* [*] */ + CHI_110_1(z->S[I(0, 4)], d[0], t, d[2]); /* * [*] . -> * */ + CHI_101_0(z->S[I(1, 4)], t, d[2], d[3]); /* [*] . * -> . */ + CHI_010_0(z->S[I(2, 4)], d[2], d[3], d[4]); /* . * . -> . */ + CHI_101_0(z->S[I(3, 4)], d[3], d[4], d[0]); /* * * . -> . */ + CHI_010_0(z->S[I(4, 4)], d[4], d[0], d[1]); /* * . . -> . */ /* And we're done. */ #undef THETA_RHO diff --git a/symm/latinpoly-def.h b/symm/latinpoly-def.h new file mode 100644 index 00000000..af917fad --- /dev/null +++ b/symm/latinpoly-def.h @@ -0,0 +1,469 @@ +/* -*-c-*- + * + * AEAD schemes based on Salsa20/ChaCha and Poly1305 + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef CATACOMB_LATINPOLY_DEF_H +#define CATACOMB_LATINPOLY_DEF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include +#include +#include + +#ifndef CATACOMB_ARENA_H +# include "arena.h" +#endif + +#ifndef CATACOMB_CT_H +# include "ct.h" +#endif + +#ifndef CATACOMB_GAEAD_H +# include "gaead.h" +#endif + +#ifndef CATACOMB_KEYSZ_H +# include "keysz.h" +#endif + +#ifndef CATACOMB_LATINPOLY_H +# include "latinpoly.h" +#endif + +#ifndef CATACOMB_PARANOIA_H +# include "paranoia.h" +#endif + +#ifndef CATACOMB_POLY1305_H +# include "poly1305.h" +#endif + +#ifndef CATACOMB_SALSA20_H +# include "salsa20.h" +#endif + +/*----- Data structures ---------------------------------------------------*/ + +typedef struct latinpoly_aad { + gaead_aad a; + poly1305_ctx poly; +} latinpoly_aad; + +typedef struct latinpoly_key { + gaead_key k; + octet key[SALSA20_KEYSZ]; + size_t ksz; +} latinpoly_key; + +/*----- Common definitions ------------------------------------------------*/ + +/* Tables. */ +extern const octet latinpoly_noncesz[], latinpoly_tagsz[]; + +/* AAD methods. */ +extern void latinpoly_aadhash_poly1305(gaead_aad */*a*/, + const void */*h*/, size_t /*hsz*/); +extern void latinpoly_aadhash_naclbox(gaead_aad */*a*/, + const void */*h*/, size_t /*hsz*/); +extern void latinpoly_aaddestroy(gaead_aad */*a*/); + +/* Variants. */ +enum { LPVAR_NACLBOX, LPVAR_POLY1305 }; + +/* --- @latinpoly_tag@ --- * + * + * Arguments: @const poly1305_ctx *aad@ = Poly1305 context hashing AAD + * @poly1305_ctx *ct@ = Poly1305 context hashing ciphertext + * @void *tag@ = where to write the tag + * + * Returns: --- + * + * Use: Completes a Latin-dance-Poly1305 tag, combining the AAD and + * ciphertext hashes, appending their lengths, and writing the + * final masked hash to @tag@. The @ct@ context is clobbered. + */ + +extern void latinpoly_tag(const poly1305_ctx */*aad*/, + poly1305_ctx */*ct*/, void */*tag*/); + +/*----- Macros ------------------------------------------------------------*/ + +#define LATINPOLY_DEF(latin, base, name) \ + \ +/* Utilities. */ \ + \ +/* Reinitialize the stream cipher and hash state given a new nonce. */ \ +static int reinit_##latin(x##latin##_ctx *ctx, int var, \ + poly1305_ctx *aadpoly, poly1305_ctx *ctpoly, \ + const void *n, size_t nsz) \ +{ \ + poly1305_key pk; \ + octet b[POLY1305_KEYSZ + POLY1305_MASKSZ]; \ + \ + switch (nsz) { \ + case SALSA20_NONCESZ: \ + memcpy(ctx->s.a, ctx->k, sizeof(ctx->k)); \ + base##_setnonce(&ctx->s, n); \ + break; \ + case SALSA20_IETF_NONCESZ: \ + memcpy(ctx->s.a, ctx->k, sizeof(ctx->k)); \ + base##_setnonce_ietf(&ctx->s, n); \ + break; \ + case XSALSA20_NONCESZ: \ + x##latin##_setnonce(ctx, n); \ + break; \ + default: \ + return (-1); \ + } \ + \ + latin##_encrypt(&ctx->s, 0, b, sizeof(b)); \ + poly1305_keyinit(&pk, b, POLY1305_KEYSZ); \ + poly1305_macinit(ctpoly, &pk, b + POLY1305_KEYSZ); \ + switch (var) { \ + case LPVAR_NACLBOX: \ + aadpoly->count = 0; aadpoly->nbuf = 0; \ + break; \ + case LPVAR_POLY1305: \ + poly1305_macinit(aadpoly, &pk, b + POLY1305_KEYSZ); \ + latin##_encrypt(&ctx->s, 0, 0, SALSA20_OUTSZ - sizeof(b)); \ + break; \ + default: \ + assert(0); \ + } \ + return (0); \ +} \ + \ +/* AAD operations. */ \ + \ +static const gaead_aadops gaops_##latin##_poly1305 = \ + { &latin##_poly1305, 0, latinpoly_aadhash_poly1305, latinpoly_aaddestroy }; \ + \ +static const gaead_aadops gaops_##latin##_naclbox = \ + { &latin##_naclbox, 0, latinpoly_aadhash_naclbox, latinpoly_aaddestroy }; \ + \ +/* Encryption operations. */ \ + \ +typedef struct gectx_##latin { \ + gaead_enc e; \ + latinpoly_aad aad; \ + x##latin##_ctx ctx; \ + poly1305_ctx poly; \ +} gectx_##latin; \ + \ +static gaead_aad *geaad_##latin(gaead_enc *e) \ + { gectx_##latin *enc = (gectx_##latin *)e; return (&enc->aad.a); } \ + \ +static int gereinit_##latin##_poly1305(gaead_enc *e, \ + const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gectx_##latin *enc = (gectx_##latin *)e; \ + return (reinit_##latin(&enc->ctx, LPVAR_POLY1305, \ + &enc->aad.poly, &enc->poly, n, nsz)); \ +} \ + \ +static int gereinit_##latin##_naclbox(gaead_enc *e, \ + const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gectx_##latin *enc = (gectx_##latin *)e; \ + return (reinit_##latin(&enc->ctx, LPVAR_NACLBOX, \ + &enc->aad.poly, &enc->poly, n, nsz)); \ +} \ + \ +static int geenc_##latin(gaead_enc *e, \ + const void *m, size_t msz, buf *b) \ +{ \ + gectx_##latin *enc = (gectx_##latin *)e; \ + void *q; \ + \ + if (msz) { q = buf_get(b, msz); if (!q) return (-1); } \ + else q = 0; \ + latin##_encrypt(&enc->ctx.s, m, q, msz); \ + poly1305_hash(&enc->poly, q, msz); \ + return (0); \ +} \ + \ +static int gedone_##latin##_common(gectx_##latin *enc, \ + const latinpoly_aad *aad, \ + buf *b, size_t tsz) \ +{ \ + if (tsz != POLY1305_TAGSZ) return (-1); \ + assert((!enc->aad.poly.count && !enc->aad.poly.nbuf && !aad) || \ + aad == &enc->aad); \ + if (!BOK(b)) return (-1); \ + return (0); \ +} \ + \ +static int gedone_##latin##_poly1305(gaead_enc *e, const gaead_aad *a, \ + buf *b, void *t, size_t tsz) \ +{ \ + gectx_##latin *enc = (gectx_##latin *)e; \ + const latinpoly_aad *aad = (const latinpoly_aad *)a; \ + \ + if (gedone_##latin##_common(enc, aad, b, tsz)) return (-1); \ + latinpoly_tag(aad ? &aad->poly : 0, &enc->poly, t); \ + return (0); \ +} \ + \ +static int gedone_##latin##_naclbox(gaead_enc *e, const gaead_aad *a, \ + buf *b, void *t, size_t tsz) \ +{ \ + gectx_##latin *enc = (gectx_##latin *)e; \ + const latinpoly_aad *aad = (const latinpoly_aad *)a; \ + \ + if (gedone_##latin##_common(enc, aad, b, tsz)) return (-1); \ + poly1305_done(&enc->poly, t); \ + return (0); \ +} \ + \ +static void gedestroy_##latin(gaead_enc *e) \ + { gectx_##latin *enc = (gectx_##latin *)e; BURN(*enc); S_DESTROY(enc); } \ + \ +static gaead_encops geops_##latin##_poly1305 = \ + { &latin##_poly1305, geaad_##latin, gereinit_##latin##_poly1305, \ + geenc_##latin, gedone_##latin##_poly1305, gedestroy_##latin }; \ + \ +static gaead_encops geops_##latin##_naclbox = \ + { &latin##_naclbox, geaad_##latin, gereinit_##latin##_naclbox, \ + geenc_##latin, gedone_##latin##_naclbox, gedestroy_##latin }; \ + \ +/* Decryption operations. */ \ + \ +typedef struct gdctx_##latin { \ + gaead_dec d; \ + latinpoly_aad aad; \ + x##latin##_ctx ctx; \ + poly1305_ctx poly; \ +} gdctx_##latin; \ + \ +static gaead_aad *gdaad_##latin(gaead_dec *d) \ + { gdctx_##latin *dec = (gdctx_##latin *)d; return (&dec->aad.a); } \ + \ +static int gdreinit_##latin##_poly1305(gaead_dec *d, \ + const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gdctx_##latin *dec = (gdctx_##latin *)d; \ + return (reinit_##latin(&dec->ctx, LPVAR_POLY1305, \ + &dec->aad.poly, &dec->poly, n, nsz)); \ +} \ + \ +static int gdreinit_##latin##_naclbox(gaead_dec *d, \ + const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gdctx_##latin *dec = (gdctx_##latin *)d; \ + return (reinit_##latin(&dec->ctx, LPVAR_NACLBOX, \ + &dec->aad.poly, &dec->poly, n, nsz)); \ +} \ + \ +static int gddec_##latin(gaead_dec *d, \ + const void *c, size_t csz, buf *b) \ +{ \ + gdctx_##latin *dec = (gdctx_##latin *)d; \ + void *q; \ + \ + if (csz) { q = buf_get(b, csz); if (!q) return (-1); } \ + else q = 0; \ + poly1305_hash(&dec->poly, c, csz); \ + latin##_encrypt(&dec->ctx.s, c, q, csz); \ + return (0); \ +} \ + \ +static int gddone_##latin##_common(gdctx_##latin *dec, \ + const latinpoly_aad *aad, \ + buf *b, size_t tsz) \ +{ \ + if (tsz != POLY1305_TAGSZ) return (-1); \ + assert((!dec->aad.poly.count && !dec->aad.poly.nbuf && !aad) || \ + aad == &dec->aad); \ + if (!BOK(b)) return (-1); \ + return (0); \ +} \ + \ +static int gddone_##latin##_poly1305(gaead_dec *d, const gaead_aad *a, \ + buf *b, const void *t, size_t tsz) \ +{ \ + gdctx_##latin *dec = (gdctx_##latin *)d; \ + const latinpoly_aad *aad = (const latinpoly_aad *)a; \ + octet u[POLY1305_TAGSZ]; \ + \ + if (gddone_##latin##_common(dec, aad, b, tsz)) return (-1); \ + latinpoly_tag(aad ? &aad->poly : 0, &dec->poly, u); \ + if (ct_memeq(t, u, POLY1305_TAGSZ)) return (+1); \ + else return (0); \ +} \ + \ +static int gddone_##latin##_naclbox(gaead_dec *d, const gaead_aad *a, \ + buf *b, const void *t, size_t tsz) \ +{ \ + gdctx_##latin *dec = (gdctx_##latin *)d; \ + const latinpoly_aad *aad = (const latinpoly_aad *)a; \ + octet u[POLY1305_TAGSZ]; \ + \ + if (gddone_##latin##_common(dec, aad, b, tsz)) return (-1); \ + poly1305_done(&dec->poly, u); \ + if (ct_memeq(t, u, POLY1305_TAGSZ)) return (+1); \ + else return (0); \ +} \ + \ +static void gddestroy_##latin(gaead_dec *d) \ + { gdctx_##latin *dec = (gdctx_##latin *)d; BURN(*dec); S_DESTROY(dec); } \ + \ +static gaead_decops gdops_##latin##_poly1305 = \ + { &latin##_poly1305, gdaad_##latin, gdreinit_##latin##_poly1305, \ + gddec_##latin, gddone_##latin##_poly1305, gddestroy_##latin }; \ + \ +static gaead_decops gdops_##latin##_naclbox = \ + { &latin##_poly1305, gdaad_##latin, gdreinit_##latin##_naclbox, \ + gddec_##latin, gddone_##latin##_naclbox, gddestroy_##latin }; \ + \ +/* Key operations. */ \ + \ +static gaead_enc *gkenc_##latin##_poly1305(const gaead_key *k, \ + const void *n, size_t nsz, \ + size_t hsz, size_t msz, \ + size_t tsz) \ +{ \ + latinpoly_key *key = (latinpoly_key *)k; \ + gectx_##latin *enc = S_CREATE(gectx_##latin); \ + \ + enc->e.ops = &geops_##latin##_poly1305; \ + enc->aad.a.ops = &gaops_##latin##_poly1305; \ + x##latin##_init(&enc->ctx, key->key, key->ksz, 0); \ + if (reinit_##latin(&enc->ctx, LPVAR_POLY1305, \ + &enc->aad.poly, &enc->poly, n, nsz)) \ + { gedestroy_##latin(&enc->e); return (0); } \ + return (&enc->e); \ +} \ + \ +static gaead_enc *gkenc_##latin##_naclbox(const gaead_key *k, \ + const void *n, size_t nsz, \ + size_t hsz, size_t msz, \ + size_t tsz) \ +{ \ + latinpoly_key *key = (latinpoly_key *)k; \ + gectx_##latin *enc = S_CREATE(gectx_##latin); \ + \ + enc->e.ops = &geops_##latin##_naclbox; \ + enc->aad.a.ops = &gaops_##latin##_naclbox; \ + x##latin##_init(&enc->ctx, key->key, key->ksz, 0); \ + if (reinit_##latin(&enc->ctx, LPVAR_NACLBOX, \ + &enc->aad.poly, &enc->poly, n, nsz)) \ + { gedestroy_##latin(&enc->e); return (0); } \ + return (&enc->e); \ +} \ + \ +static gaead_dec *gkdec_##latin##_poly1305(const gaead_key *k, \ + const void *n, size_t nsz, \ + size_t hsz, size_t msz, \ + size_t tsz) \ +{ \ + latinpoly_key *key = (latinpoly_key *)k; \ + gdctx_##latin *dec = S_CREATE(gdctx_##latin); \ + \ + dec->d.ops = &gdops_##latin##_poly1305; \ + dec->aad.a.ops = &gaops_##latin##_poly1305; \ + x##latin##_init(&dec->ctx, key->key, key->ksz, 0); \ + if (reinit_##latin(&dec->ctx, LPVAR_POLY1305, \ + &dec->aad.poly, &dec->poly, n, nsz)) \ + { gddestroy_##latin(&dec->d); return (0); } \ + return (&dec->d); \ +} \ + \ +static gaead_dec *gkdec_##latin##_naclbox(const gaead_key *k, \ + const void *n, size_t nsz, \ + size_t hsz, size_t msz, \ + size_t tsz) \ +{ \ + latinpoly_key *key = (latinpoly_key *)k; \ + gdctx_##latin *dec = S_CREATE(gdctx_##latin); \ + \ + dec->d.ops = &gdops_##latin##_naclbox; \ + dec->aad.a.ops = &gaops_##latin##_naclbox; \ + x##latin##_init(&dec->ctx, key->key, key->ksz, 0); \ + if (reinit_##latin(&dec->ctx, LPVAR_NACLBOX, \ + &dec->aad.poly, &dec->poly, n, nsz)) \ + { gddestroy_##latin(&dec->d); return (0); } \ + return (&dec->d); \ +} \ + \ +static void gkdestroy_##latin(gaead_key *k) \ + { latinpoly_key *key = (latinpoly_key *)k; BURN(*key); S_DESTROY(key); } \ + \ +static const gaead_keyops gkops_##latin##_poly1305 = \ + { &latin##_poly1305, 0, \ + gkenc_##latin##_poly1305, gkdec_##latin##_poly1305, \ + gkdestroy_##latin }; \ + \ +static const gaead_keyops gkops_##latin##_naclbox = \ + { &latin##_naclbox, 0, \ + gkenc_##latin##_naclbox, gkdec_##latin##_naclbox, \ + gkdestroy_##latin }; \ + \ +/* Class definition. */ \ + \ +static gaead_key *gkey_##latin##_common(const gaead_keyops *ops, \ + const void *k, size_t ksz) \ +{ \ + latinpoly_key *key = S_CREATE(latinpoly_key); \ + \ + key->k.ops = ops; \ + KSZ_ASSERT(latin, ksz); memcpy(key->key, k, ksz); key->ksz = ksz; \ + return (&key->k); \ +} \ + \ +static gaead_key *gkey_##latin##_poly1305(const void *k, size_t ksz) \ + { return (gkey_##latin##_common(&gkops_##latin##_poly1305, k, ksz)); } \ + \ +static gaead_key *gkey_##latin##_naclbox(const void *k, size_t ksz) \ + { return (gkey_##latin##_common(&gkops_##latin##_naclbox, k, ksz)); } \ + \ +const gcaead latin##_poly1305 = { \ + name "-poly1305", latin##_keysz, latinpoly_noncesz, latinpoly_tagsz, \ + 64, 0, 0, AEADF_AADNDEP, \ + gkey_##latin##_poly1305 \ +}; \ + \ +const gcaead latin##_naclbox = { \ + name "-naclbox", latin##_keysz, latinpoly_noncesz, latinpoly_tagsz, \ + 64, 0, 0, AEADF_AADNDEP | AEADF_NOAAD, \ + gkey_##latin##_naclbox \ +}; + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/latinpoly-test.c b/symm/latinpoly-test.c new file mode 100644 index 00000000..5a914e50 --- /dev/null +++ b/symm/latinpoly-test.c @@ -0,0 +1,116 @@ +/* -*-c-*- + * + * Testing for AEAD schemes based on Salsa20/ChaCha and Poly1305 + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "latinpoly-def.h" + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @latinpoly_test@ --- * + * + * Arguments: @gcaead *aec@ = authenticated encryption class to test + * @dstr *v@ = pointer to test-vector + * + * Returns: Nonzero if the test passed, zero on failure. + */ + +int latinpoly_test(const gcaead *aec, dstr *v) +{ + gaead_key *k; + gaead_aad *a; + gaead_enc *e; gaead_dec *d; + dstr out = DSTR_INIT, tag = DSTR_INIT; + buf b; + int rc; + int ok = 1; + + k = GAEAD_KEY(aec, v[0].buf, v[0].len); + + dstr_reset(&out); dstr_ensure(&out, v[3].len); + dstr_reset(&tag); dstr_ensure(&tag, POLY1305_TAGSZ); + e = GAEAD_ENC(k, v[1].buf, v[1].len, 0, 0, 0); + a = GAEAD_AAD(e); GAEAD_HASH(a, v[2].buf, v[2].len); + buf_init(&b, out.buf, out.sz); + rc = GAEAD_ENCRYPT(e, v[3].buf, v[3].len, &b); + if (rc) { printf("!! encrypt reports failure\n"); goto encfail; } + rc = GAEAD_DONE(e, a, &b, tag.buf, POLY1305_TAGSZ); + if (rc) { printf("!! encryptdone reports failure\n"); goto encfail; } + + out.len = BLEN(&b); tag.len = POLY1305_TAGSZ; + if (out.len != v[4].len || memcmp(out.buf, v[4].buf, v[4].len) || + memcmp(tag.buf, v[5].buf, v[5].len)) { + encfail: + ok = 0; + printf("\n%s encrypt FAILED", aec->name); + printf("\n key = "); type_hex.dump(&v[0], stdout); + printf("\n nonce = "); type_hex.dump(&v[1], stdout); + printf("\n header = "); type_hex.dump(&v[2], stdout); + printf("\n message = "); type_hex.dump(&v[3], stdout); + printf("\n exp ct = "); type_hex.dump(&v[4], stdout); + printf("\n calc ct = "); type_hex.dump(&out, stdout); + printf("\n exp tag = "); type_hex.dump(&v[5], stdout); + printf("\ncalc tag = "); type_hex.dump(&tag, stdout); + putchar('\n'); + } + GAEAD_DESTROY(a); + GAEAD_DESTROY(e); + + dstr_reset(&out); dstr_ensure(&out, v[3].len); + dstr_reset(&tag); dstr_ensure(&tag, POLY1305_TAGSZ); + d = GAEAD_DEC(k, v[1].buf, v[1].len, 0, 0, 0); + a = GAEAD_AAD(d); GAEAD_HASH(a, v[2].buf, v[2].len); + buf_init(&b, out.buf, out.sz); + rc = GAEAD_DECRYPT(d, v[4].buf, v[4].len, &b); + if (rc) { printf("!! decrypt reports failure\n"); goto decfail; } + rc = GAEAD_DONE(e, a, &b, v[5].buf, POLY1305_TAGSZ); + if (rc < 0) { printf("!! decryptdone reports failure\n"); goto decfail; } + + out.len = BLEN(&b); tag.len = POLY1305_TAGSZ; + if (out.len != v[3].len || memcmp(out.buf, v[3].buf, v[3].len) || !rc) { + decfail: + ok = 0; + printf("\ndecrypt FAILED"); + printf("\n key = "); type_hex.dump(&v[0], stdout); + printf("\n nonce = "); type_hex.dump(&v[1], stdout); + printf("\n header = "); type_hex.dump(&v[2], stdout); + printf("\n cipher = "); type_hex.dump(&v[4], stdout); + printf("\n exp msg = "); type_hex.dump(&v[3], stdout); + printf("\ncalc msg = "); type_hex.dump(&out, stdout); + printf("\n tag = "); type_hex.dump(&v[5], stdout); + printf("\n verify %s", rc > 0 ? "ok" : "FAILED"); + putchar('\n'); + } + GAEAD_DESTROY(a); + GAEAD_DESTROY(d); + + GAEAD_DESTROY(k); + dstr_destroy(&out); dstr_destroy(&tag); + return (ok); +} + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/symm/latinpoly-test.h b/symm/latinpoly-test.h new file mode 100644 index 00000000..2cafef33 --- /dev/null +++ b/symm/latinpoly-test.h @@ -0,0 +1,65 @@ +/* -*-c-*- + * + * Testing for AEAD schemes based on Salsa20/ChaCha and Poly1305 + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef CATACOMB_LATINPOLY_TEST_H +#define CATACOMB_LATINPOLY_TEST_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include +#include + +#ifndef CATACOMB_GAEAD_H +# include "gaead.h" +#endif + +/*----- Functions provided ------------------------------------------------*/ + +/* --- @latinpoly_test@ --- * + * + * Arguments: @gcaead *aec@ = authenticated encryption class to test + * @dstr *v@ = pointer to test-vector + * + * Returns: Nonzero if the test passed, zero on failure. + * + * Use: Checks a test vector. This internal function is not + * available outside of Catacomb's build tree. + */ + +extern int latinpoly_test(const gcaead */*aec*/, dstr */*v*/); + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/latinpoly.c b/symm/latinpoly.c new file mode 100644 index 00000000..29ba71ab --- /dev/null +++ b/symm/latinpoly.c @@ -0,0 +1,97 @@ +/* -*-c-*- + * + * AEAD schemes based on Salsa20/ChaCha and Poly1305 + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "config.h" + +#include +#include + +#include "gaead.h" +#include "keysz.h" +#include "latinpoly-def.h" + +#include "poly1305.h" +#include "salsa20.h" + +/*----- Common definitions ------------------------------------------------*/ + +const octet + latinpoly_noncesz[] = { KSZ_SET, SALSA20_NONCESZ, SALSA20_IETF_NONCESZ, + XSALSA20_NONCESZ, 0 }, + latinpoly_tagsz[] = { KSZ_SET, POLY1305_TAGSZ, 0 }; + +/* AAD handling. */ + +void latinpoly_aadhash_poly1305(gaead_aad *a, const void *h, size_t hsz) +{ + latinpoly_aad *aad = (latinpoly_aad *)a; + poly1305_hash(&aad->poly, h, hsz); +} + +void latinpoly_aadhash_naclbox(gaead_aad *a, const void *h, size_t hsz) + { assert(!hsz); } + +void latinpoly_aaddestroy(gaead_aad *a) { ; } + +/* --- @latinpoly_tag@ --- * + * + * Arguments: @const poly1305_ctx *aad@ = Poly1305 context hashing AAD + * @poly1305_ctx *ct@ = Poly1305 context hashing ciphertext + * @void *tag@ = where to write the tag + * + * Returns: --- + * + * Use: Completes a Latin-dance-Poly1305 tag, combining the AAD and + * ciphertext hashes, appending their lengths, and writing the + * final masked hash to @tag@. The @ct@ context is clobbered. + */ + +/* Write the length of data pushed through Poly1305 as a 64-bit integer. */ +static void putlen(octet *p, const poly1305_ctx *poly) +{ + uint32 lo = U32((poly->count << 4) | poly->nbuf), + hi = U32(poly->count >> 28); + STORE32_L(p + 0, lo); STORE32_L(p + 4, hi); +} + +void latinpoly_tag(const poly1305_ctx *aad, poly1305_ctx *ct, void *tag) +{ + octet b[16]; + poly1305_ctx t; + + putlen(b + 8, ct); poly1305_flushzero(ct); + if (!aad) memset(b, 0, 8); + else { + putlen(b + 0, aad); + t = *aad; poly1305_flushzero(&t); poly1305_concat(ct, &t, ct); + } + poly1305_hash(ct, b, 16); poly1305_done(ct, tag); +} + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/symm/latinpoly.h b/symm/latinpoly.h new file mode 100644 index 00000000..a9bb25ee --- /dev/null +++ b/symm/latinpoly.h @@ -0,0 +1,82 @@ +/* -*-c-*- + * + * AEAD schemes based on Salsa20/ChaCha and Poly1305 + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Notes on this construction ----------------------------------------* + * + * The AEAD class @chacha20_poly1305@ with a 96-bit nonce is exactly the + * scheme specified in RFC7539. This implementation extends that + * specification in two ways: + * + * * It permits ciphers other than ChaCha20: specifically ChaCha%$r$% and + * Salsa20/%$r$% with %$r \in \{ 8, 12, 20 \}$%. + * + * * It allows nonces of 64, 96, and 192 bits. A 64-bit nonce matches + * Bernstein's original specification of Salsa20 and ChaCha; the 96-bit + * nonce matches RFC7539; and the 192-bit nonce matches Bernstein's + * XSalsa20. The implementation uses XSalsa20 or XChaCha as appropriate + * automatically based on the provided nonce length. + * + * These extensions do not significantly affect Procter's security analysis + * except that an application should not mix nonce sizes with the same key. + * (It is possible to do this safely, but it requires detailed understanding + * of how everything fits together and isn't worth the effort.) + * + * The @salsa20_naclbox@ with a 192-bit nonce is exactly the scheme + * implemented in Bernstein's `NaCl' library as @crypto_secretbox@, except + * that it's flexible regarding tag placement rather than insisting on + * prefixing it to the ciphertext. Unlike NaCl, we provide a restartable + * interface, and allow the use of other ciphers and nonce lengths. + */ + +#ifndef CATACOMB_LATINPOLY_H +#define CATACOMB_LATINPOLY_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#ifndef CATACOMB_GAEAD_H +# include "gaead.h" +#endif + +/*----- Definitions -------------------------------------------------------*/ + +extern const gcaead + chacha20_poly1305, chacha12_poly1305, chacha8_poly1305, + chacha20_naclbox, chacha12_naclbox, chacha8_naclbox, + salsa20_poly1305, salsa2012_poly1305, salsa208_poly1305, + salsa20_naclbox, salsa2012_naclbox, salsa208_naclbox; + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/mgf-def.h b/symm/mgf-def.h index 832cd074..0b2df3d6 100644 --- a/symm/mgf-def.h +++ b/symm/mgf-def.h @@ -82,16 +82,10 @@ const octet pre##_mgfkeysz[] = { KSZ_ANY, PRE##_HASHSZ }; \ */ \ \ void pre##_mgfkeybegin(pre##_mgfctx *k) \ -{ \ - k->c = 0; \ - k->bsz = 0; \ - pre##_init(&k->k); \ -} \ + { k->c = 0; k->off = 0; pre##_init(&k->k); } \ \ void pre##_mgfkeyadd(pre##_mgfctx *k, const void *p, size_t sz) \ -{ \ - pre##_hash(&k->k, p, sz); \ -} \ + { pre##_hash(&k->k, p, sz); } \ \ /* ---- @pre_mgfinit@ --- * \ * \ @@ -106,12 +100,7 @@ void pre##_mgfkeyadd(pre##_mgfctx *k, const void *p, size_t sz) \ */ \ \ void pre##_mgfinit(pre##_mgfctx *k, const void *p, size_t sz) \ -{ \ - k->c = 0; \ - k->bsz = 0; \ - pre##_init(&k->k); \ - pre##_hash(&k->k, p, sz); \ -} \ + { k->c = 0; k->off = 0; pre##_init(&k->k); pre##_hash(&k->k, p, sz); } \ \ /* --- @pre_mgfencrypt@ --- * \ * \ @@ -133,54 +122,35 @@ void pre##_mgfinit(pre##_mgfctx *k, const void *p, size_t sz) \ void pre##_mgfencrypt(pre##_mgfctx *k, const void *s, \ void *d, size_t sz) \ { \ + pre##_ctx h; \ const octet *ss = s; \ octet *dd = d; \ + const octet *p; \ + size_t off; \ \ /* --- Empty the buffer if there's anything there --- */ \ \ - if (k->bsz) { \ - const octet *p = k->buf + PRE##_HASHSZ - k->bsz; \ - size_t n = sz > k->bsz ? k->bsz : sz; \ - sz -= n; \ - k->bsz -= n; \ - if (dd) { \ - if (!ss) { \ - memcpy(dd, p, n); \ - dd += n; \ - } else { \ - while (n) { \ - *dd++ = *ss++ ^ *p++; \ - n--; \ - } \ - } \ - } \ + if (k->off) { \ + p = k->b + PRE##_HASHSZ - k->off; \ + off = sz > k->off ? k->off : sz; \ + sz -= off; k->off -= off; \ + if (!dd) /* do nothing */; \ + else if (!ss) { memcpy(dd, p, off); dd += off; } \ + else while (off--) *dd++ = *ss++ ^ *p++; \ } \ \ /* --- While necessary, generate some more mask --- */ \ \ while (sz) { \ - pre##_ctx c = k->k; /* Not quick! */ \ - size_t n; \ - \ - STORE32(k->buf, k->c); \ - k->c++; \ - pre##_hash(&c, k->buf, 4); \ - pre##_done(&c, k->buf); \ - n = sz > PRE##_HASHSZ ? PRE##_HASHSZ : sz; \ - k->bsz = PRE##_HASHSZ - n; \ - sz -= n; \ - if (dd) { \ - const octet *p = k->buf; \ - if (!ss) { \ - memcpy(dd, p, n); \ - dd += n; \ - } else { \ - while (n) { \ - *dd++ = *ss++ ^ *p++; \ - n--; \ - } \ - } \ - } \ + STORE32(k->b, k->c); k->c++; \ + h = k->k; pre##_hash(&h, k->b, 4); pre##_done(&h, k->b); \ + off = sz > PRE##_HASHSZ ? PRE##_HASHSZ : sz; \ + k->off = PRE##_HASHSZ - off; \ + sz -= off; \ + p = k->b; \ + if (!dd) /* do nothing */; \ + else if (!ss) { memcpy(dd, p, off); dd += off; } \ + else while (off--) *dd++ = *ss++ ^ *p++; \ } \ } \ \ @@ -196,10 +166,7 @@ void pre##_mgfencrypt(pre##_mgfctx *k, const void *s, \ */ \ \ void pre##_mgfsetindex(pre##_mgfctx *k, uint32 c) \ -{ \ - k->c = c; \ - k->bsz = 0; \ -} \ + { k->c = c; k->off = 0; } \ \ /* --- Generic cipher interface --- */ \ \ @@ -219,17 +186,10 @@ static gcipher *ginit(const void *k, size_t sz) \ } \ \ static void gencrypt(gcipher *c, const void *s, void *t, size_t sz) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_mgfencrypt(&g->k, s, t, sz); \ -} \ + { gctx *g = (gctx *)c; pre##_mgfencrypt(&g->k, s, t, sz); } \ \ static void gdestroy(gcipher *c) \ -{ \ - gctx *g = (gctx *)c; \ - BURN(*g); \ - S_DESTROY(g); \ -} \ + { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); } \ \ static const gcipher_ops gops = { \ &pre##_mgf, \ @@ -320,10 +280,7 @@ static uint32 grword(grand *r) \ } \ \ static void grfill(grand *r, void *p, size_t sz) \ -{ \ - grctx *g = (grctx *)r; \ - pre##_mgfencrypt(&g->k, 0, p, sz); \ -} \ + { grctx *g = (grctx *)r; pre##_mgfencrypt(&g->k, 0, p, sz); } \ \ static const grand_ops grops = { \ name "-mgf", \ @@ -359,9 +316,7 @@ MGF_TESTX(PRE, pre, name, fname) #ifdef TEST_RIG -#include - -#include "daftstory.h" +#include "modes-test.h" /* --- @MGF_TEST@ --- * * @@ -372,81 +327,23 @@ MGF_TESTX(PRE, pre, name, fname) #define MGF_TESTX(PRE, pre, name, fname) \ \ -/* --- Initial plaintext for the test --- */ \ - \ -static const octet text[] = TEXT; \ +static pre##_mgfctx ctx; \ \ -/* --- Key and IV to use --- */ \ +static void pre##_mgf_test_setup(const octet *k, size_t ksz) \ + { pre##_mgfinit(&ctx, k, ksz); } \ \ -static const octet key[] = KEY; \ +static void pre##_mgf_test_reset(const octet *iv) \ + { pre##_mgfsetindex(&ctx, 0); } \ \ -/* --- Buffers for encryption and decryption output --- */ \ +static void pre##_mgf_test_enc(const octet *s, octet *d, size_t sz) \ + { pre##_mgfencrypt(&ctx, s, d, sz); } \ \ -static octet ct[sizeof(text)]; \ -static octet pt[sizeof(text)]; \ - \ -static void hexdump(const octet *p, size_t sz) \ +int main(int argc, char *argv[]) \ { \ - const octet *q = p + sz; \ - for (sz = 0; p < q; p++, sz++) { \ - printf("%02x", *p); \ - if ((sz + 1) % PRE##_HASHSZ == 0) \ - putchar(':'); \ - } \ -} \ - \ -int main(void) \ -{ \ - size_t sz = 0, rest; \ - pre##_mgfctx ctx; \ - int status = 0; \ - int done = 0; \ - \ - size_t keysz = strlen((const char *)key); \ - \ - fputs(name "-mgf: ", stdout); \ - \ - pre##_mgfinit(&ctx, key, keysz); \ - \ - while (sz <= sizeof(text)) { \ - rest = sizeof(text) - sz; \ - memcpy(ct, text, sizeof(text)); \ - pre##_mgfsetindex(&ctx, 0); \ - pre##_mgfencrypt(&ctx, ct, ct, sz); \ - pre##_mgfencrypt(&ctx, ct + sz, ct + sz, rest); \ - memcpy(pt, ct, sizeof(text)); \ - pre##_mgfsetindex(&ctx, 0); \ - pre##_mgfencrypt(&ctx, pt, pt, rest); \ - pre##_mgfencrypt(&ctx, pt + rest, pt + rest, sz); \ - if (memcmp(pt, text, sizeof(text)) == 0) { \ - done++; \ - if (sizeof(text) < 40 || done % 8 == 0) \ - fputc('.', stdout); \ - if (done % 480 == 0) \ - fputs("\n\t", stdout); \ - fflush(stdout); \ - } else { \ - printf("\nError (sz = %lu)\n", (unsigned long)sz); \ - status = 1; \ - printf("\tplaintext = "); hexdump(text, sz); \ - printf(", "); hexdump(text + sz, rest); \ - fputc('\n', stdout); \ - printf("\tciphertext = "); hexdump(ct, sz); \ - printf(", "); hexdump(ct + sz, rest); \ - fputc('\n', stdout); \ - printf("\trecovered text = "); hexdump(pt, sz); \ - printf(", "); hexdump(pt + sz, rest); \ - fputc('\n', stdout); \ - fputc('\n', stdout); \ - } \ - if (sz < 63) \ - sz++; \ - else \ - sz += 9; \ - } \ - \ - fputs(status ? " failed\n" : " ok\n", stdout); \ - return (status); \ + return test_encmode(fname "-mgf", 0, PRE##_HASHSZ, 1, 0, \ + pre##_mgf_test_setup, pre##_mgf_test_reset, \ + pre##_mgf_test_enc, pre##_mgf_test_enc, \ + argc, argv); \ } #else diff --git a/symm/mgf.h b/symm/mgf.h index d5b0fd1b..934f0127 100644 --- a/symm/mgf.h +++ b/symm/mgf.h @@ -61,8 +61,8 @@ typedef struct pre##_mgfctx { \ pre##_ctx k; /* Underlying key context */ \ uint32 c; /* Counter */ \ - octet buf[PRE##_HASHSZ]; /* Output buffer */ \ - size_t bsz; /* Size of buffered data */ \ + octet b[PRE##_HASHSZ]; /* Output buffer */ \ + unsigned off; /* Size of buffered data */ \ } pre##_mgfctx; \ \ /* --- Other useful constants --- */ \ diff --git a/symm/modes-test.c b/symm/modes-test.c new file mode 100644 index 00000000..b06d230a --- /dev/null +++ b/symm/modes-test.c @@ -0,0 +1,546 @@ +/* -*-c-*- + * + * Common code for testing encryption modes + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "modes-test.h" + +/*----- The reference data ------------------------------------------------*/ + +#ifdef SMALL_TEST +static const octet text[] = "A small piece of text for testing encryption."; +#else +#define STORY "\ +Once upon a time there were a beautiful princess, a slightly nutty wizard,\n\ +and a watermelon. Now, the watermelon had decided that it probably wasn't\n\ +going to get very far with the princess unless it did something pretty\n\ +drastic. So it asked the wizard to turn it into a handsome prince.\n\ +\n\ +At least, this is the way that the wizard viewed the situation. He might\n\ +have just hallucinated it all; those mushrooms had looked ever so nice.\n\ +\n\ +Back to the point. The watermelon had expressed its desire not to be a\n\ +watermelon any more. And the wizard was probably tripping something quite\n\ +powerful. He hunted around a bit for his staff, and mumbled something\n\ +that film directors would think of as sounding appropriately arcane and\n\ +mystical (but was, in fact, just the ingredients list for an ancient\n\ +remedy for athlete's foot) and *pop*. Cooked watermelon. Yuk.\n\ +\n\ +Later in the year, the princess tripped over the hem of her dress, fell\n\ +down a spiral staircase, and died. The king ordered dressmakers to attach\n\ +safety warnings to long dresses.\n\ +\n\ +And the wizard? Who cares?\n\ +" +static const octet text[] = STORY STORY; +#endif + +#define TEXTSZ (sizeof(text)) + +static const octet key[] = "Penguins rule OK, rhubarb cauliflower", + iv[] = "EdgewareCatacomb, parsley, sage, rosemary and thyme"; + +/*----- Static variables --------------------------------------------------*/ + +/* Encryption buffers, for ciphertext, recovered plaintext, and consistency + * reference. + */ +static octet ct[TEXTSZ], pt[TEXTSZ], ref[TEXTSZ]; + +/* A resizeable buffer for verifying regression data. */ +static octet *t = 0; size_t tsz = 0; + +/*----- Diagnostic utilities ----------------------------------------------*/ + +/* Print the @sz@-byte buffer @p@, beginning at offset @off@ within some + * larger buffer, marking block boundaries every @blksz@ bytes. + */ +static void hexdump(const octet *p, size_t sz, size_t off, size_t blksz) +{ + const octet *q = p + sz; + for (sz = 0; p < q; p++, sz++) { + printf("%02x", *p); + if ((off + sz + 1)%blksz == 0) putchar(':'); + } +} + +/* Print the buffer @p@, labelling it as @what@, splitting it into three + * pieces of sizes @sz0@, @sz1@, and @sz2@ respectively. Block boundaries + * every @blksz@ bytes are shown consistency, independent of the split + * positions. + */ +static void dump_split(const char *what, size_t blksz, const octet *p, + size_t sz0, size_t sz1, size_t sz2) +{ + printf("\t%-16s = ", what); + hexdump(p, sz0, 0, blksz); + if (sz1) { printf(", "); hexdump(p + sz0, sz1, sz0, blksz); } + if (sz2) { printf(", "); hexdump(p + sz0 + sz1, sz2, sz0 + sz1, blksz); } + fputc('\n', stdout); +} + +/*----- Regression-data utilities -----------------------------------------*/ + +/* Regression modes. We can @CHECK@ existing data, @RECORD@ new data, or + * @IGNORE@ the regression testing entirely. + */ +enum { IGNORE, RECORD, CHECK }; + +/* Read or write regression data from/to @fp@ according to @rmode@. The data + * item is described as @what@ in diagnostic messages, and consists of @sz@ + * bytes beginning at @p@. + * + * If @rmode@ is @IGNORE@, then this function does nothing; if @rmode@ is + * @RECORD@, then it writes @p@ to the output file with some framing; and if + * @rmode@ is @CHECK@ then it checks that the next chunk of data from the + * file matches @p@. + * + * Returns zero if all is well or @-1@ on a mismatch; I/O errors are fatal. + * + * Framing is trivial and consists of a 4-byte big-endian non-inclusive + * length prepended to each buffer. No padding is written to maintain + * alignment. + */ +static int regress_data(int rmode, FILE *fp, const char *what, + const void *p, size_t sz) +{ + octet b[4]; + size_t psz; + + switch (rmode) { + case IGNORE: + return (0); + case RECORD: + STORE32(b, sz); + if (!fwrite(b, 4, 1, fp) || !fwrite(p, sz, 1, fp)) + die(1, "failed to write %s: %s", what, strerror(errno)); + return (0); + case CHECK: + if (!fread(b, 4, 1, fp)) + die(1, "failed to read %s length: %s", what, + ferror(fp) ? strerror(errno) : "unexpected eof"); + psz = LOAD32(b); + if (psz != sz) + die(1, "incorrect %s length (%lu /= %lu; sync failure?)", + what, (unsigned long)psz, (unsigned long)sz); + if (tsz < sz) { xfree(t); t = xmalloc(sz); tsz = sz; } + if (!fread(t, sz, 1, fp)) + die(1, "failed to read %s: %s", what, + ferror(fp) ? strerror(errno) : "unexpected eof"); + if (memcmp(p, t, sz) != 0) return (-1); + return (0); + default: + abort(); + } +} + +/* Read or write framing data from/to @fp@ according to @rmode@. The framing + * item is describd as @what@ in diagnostic messages, and consists of @sz@ + * bytes beginning at @p@. + * + * Framing data is used to verify that a recorded regression-data file is + * still appropriate for use. A fatal error is reported on any kind of + * failure. + */ +static void regress_framing(int rmode, FILE *fp, const char *what, + const void *p, size_t sz) +{ + if (regress_data(rmode, fp, what, p, sz)) + die(1, "regression framing mismatch for %s (bug, or wrong file)", what); +} + +/* Read or write crypto data from/to @fp@ according to @rmode@. The data + * item is describd as @what@ in diagnostic messages, and consists of the + * bytes beginning at @p@. For the purposes of diagnostics, this buffer has + * been notionally split into three pieces, with sizes @sz0@, @sz1@, and + * @sz2@, respectively. + * + * If al is well, return zero. If the crypto data doesn't match the recorded + * regression data, then report the mismatch, showing the way in which the + * buffer is split, and return -1. I/O errors are fatal. + */ +static int regress_crypto(int rmode, FILE *fp, const char *what, size_t blksz, + const void *p, size_t sz0, size_t sz1, size_t sz2) +{ + int rc; + + rc = regress_data(rmode, fp, what, p, sz0 + sz1 + sz2); + if (rc) { + printf("\nRegression mismatch (split = %lu/%lu/%lu)\n", + (unsigned long)sz0, (unsigned long)sz1, (unsigned long)sz2); + dump_split("plaintext", blksz, text, sz0, sz1, sz2); + dump_split("expected ct", blksz, t, sz0, sz1, sz2); + dump_split("computed ct", blksz, p, sz0, sz1, sz2); + fputc('\n', stdout); + } + return (rc); +} + +/*----- Selecting fragment sizes ------------------------------------------*/ + +/* Return codes from @step@. */ +enum { STEP, LIMIT, RESET }; + +/* Update @*sz_inout@ the next largest suitable fragment size, up to a + * maximum of @max@. + * + * If the new size is still smaller than the maximum, then return @STEP@. If + * the size is maximal, then return @LIMIT@. If the size was previously + * maximal already, then return @RESET@. + * + * The sizes here are selected powers of two, and powers of two plus or minus + * 1, with the objective of testing how internal buffering is affected when + * the cursor is misaligned and realigned with block boundaries. + */ +static int step(size_t *sz_inout, size_t max) +{ + size_t i; + + static size_t steps[] = { 1, 7, 8, 9, 15, 16, 17, + 63, 64, 65, 255, 256, 257 }; + + if (*sz_inout == max) return (RESET); + for (i = 0; i < N(steps); i++) + if (steps[i] > *sz_inout) { + if (steps[i] < max) { *sz_inout = steps[i]; return (STEP); } + else break; + } + *sz_inout = max; return (LIMIT); +} + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @test_encmode@ --- * + * + * Arguments: @const char *name@ = name of the encryption scheme; used to + * find the regression-test filename + * @size_t ksz@ = key size to use, or zero for `don't care' + * @size_t blksz@ = block size + * @size_t minsz@ = smallest acceptable buffer size, or 1 + * @unsigned f@ = various additional flags + * @setupfn *setup@ = key-setup function + * @resetfn *reset@ = state-reset function + * @encfn *enc@ = encryption function + * @decfn *dec@ = decryption function + * @int argc@ = number of command-line arguments + * @char *argv@ = pointer to command-line argument vector + * + * Returns: Zero on success, nonzero to report failure. + * + * Use: Tests an encryption mode which doesn't have any more formal + * test vectors. + * + * The @name@ is used firstly in diagnostic output and secondly + * to form the default filename to use for regression-test data, + * as `.../symm/t/modes/NAME.regress'. + * + * The key size @ksz@ is simply passed on back to the @setup@ + * function, unless the caller passes in zero, in which case + * @test_encmode@ chooses a key size for itself. + * + * The block size @blksz@ is used in failure reports, to draw + * attention to the block structure in the various buffers, + * which may assist with diagnosis. It's also used to determine + * when to apply a consistency check: see below regarding the + * @TEMF_REFALIGN@ flag. + * + * The minimum buffer size @minsz@ expresses a limitation on the + * provided @enc@ and @dec@ functions, that they don't work on + * inputs smaller than @minsz@; accordingly, @test_encmode@ will + * not test such small sizes. This should be 1 if the mode has + * no limitation. + * + * The flags @f@ influence testing in various ways explained + * below. + * + * The caller-provided functions are assumed to act on some + * global but hidden state, + * + * * @setup@ is (currently, at least) called only once, with + * the key @k@ and its chosen size @ksz@. + * + * * @reset@ is called at the start of each encryption or + * decryption operation, to program in the initialization + * vector to use. Currently, the same IV is used in all of + * the tests, but this might not always be the case. + * + * * @enc@ is called to encrypt a source buffer @s@ and write + * the ciphertext to a destination @d@; @sz@ is the common + * size of these buffers. @d@ might be null, to discard + * output; @s@ might be null, to process all-zero input. + * + * * @dec@ is called to decrypt a source buffer @s@ and write + * the recovered plaintext to a destination @d@; @sz@ is the + * common size of these buffers. + * + * Finally, @int argc@ and @char *argv@ are the command-line + * arguments provided to @main@; @test_encmode@ parses these and + * alters its behaviour accordingly. + * + * Currently, @test_encmode@'s tests are built around a single, + * fairly large, fixed message. In each test step, the message + * is split into a number of fragments which are encrypted and + * decrypted in turn. + * + * The following tests are performed. + * + * * The fundamental `round-trip' test, which verifies that + * the message can be encrypted and then decrypted + * successfully, if the same fragment boundaries are used in + * both cases. + * + * * A `consistency' test. Some modes, such as CFB, OFB, and + * counter, are `resumable': encryption operations are + * insensitive to the position of fragment boundaries, so a + * single message can be broken into fragments without + * affecting the result. If @TEMF_REFALIGN@ is clear then + * the mode under test is verified to have this property. + * If @TEMF_REFALIGN' is set, a weaker property is verified: + * that encryption is insensitive to the position of + * /block-aligned/ fragment boundaries only. + * + * * A `regression' test, which verifies that the code + * produces the same ciphertext as a previous version. By + * setting command-line arguments appropriately, a test + * program can be told to record ciphertexts in a (binary) + * data file. Usually, instead, the program will read the + * recorded ciphertexts back and verify that it produces the + * same data. For resumable modes, it's only necessary to + * record single ciphertext, since all the other ciphertexts + * must be equal by consistency; otherwise all non-block- + * aligned splits are recorded separately. + */ + +int test_encmode(const char *name, + size_t ksz, size_t blksz, size_t minsz, unsigned f, + setupfn *setup, resetfn *reset, encfn *enc, encfn *dec, + int argc, char *argv[]) +{ + int ok = 1, refp = 0, i; + size_t sz0, sz1, sz2; + const char spinner[] = "/-\\|"; + int rmode = CHECK, spin = isatty(STDOUT_FILENO) ? 0 : -1; + int regr; + const char *rname = 0, *p; + FILE *fp; + dstr d = DSTR_INIT; + + ego(argv[0]); + + /* Parse the command-line options. */ + p = 0; i = 1; + for (;;) { + + /* Read the next argument. */ + if (!p || !*p) { + if (i >= argc) break; + p = argv[i++]; + if (strcmp(p, "--") == 0) break; + if (p[0] != '-' || p[1] == 0) { i--; break; } + p++; + } + + /* Interpret an option. */ + switch (*p++) { + case 'h': + printf("%s test driver\n" + "Usage: %s [-i] [-o|-f FILENAME]\n", QUIS, QUIS); + exit(0); + case 'i': + rmode = IGNORE; + break; + case 'o': + if (!*p) { + if (i >= argc) die(1, "option `-o' expects an argument"); + p = argv[i++]; + } + rmode = RECORD; rname = p; p = 0; + break; + case 'f': + if (!*p) { + if (i >= argc) die(1, "option `-f' expects an argument"); + p = argv[i++]; + } + rmode = CHECK; rname = p; p = 0; + break; + default: + die(1, "option `-%c' unknown", p[-1]); + } + } + + /* Check there's nothing else left. */ + if (i < argc) die(1, "trailing junk on command line"); + + /* Open the regression-data file. */ + if (rmode == IGNORE) + fp = 0; + else { + if (!rname) { + DRESET(&d); dstr_putf(&d, SRCDIR"/t/modes/%s.regress", name); + rname = xstrdup(d.buf); + } + fp = fopen(rname, rmode == RECORD ? "wb" : "rb"); + if (!fp) + die(1, "failed to open `%s' for %s: %s", rname, + rmode == RECORD ? "writing" : "reading", strerror(errno)); + } + + /* Write a header describing the file, to trap misuse for the wrong mode, + * and changes in the text. + */ + DRESET(&d); + dstr_putf(&d, "mode=%s, text=%lu", name, (unsigned long)TEXTSZ); + regress_framing(rmode, fp, "header", d.buf, d.len); + + /* Start things up. */ + printf("%s: ", name); + setup(key, ksz ? ksz: sizeof(key)); + + /* Work through various sizes of up to three fragments. The middle + * fragment is the important one, since it can be misaligned or not at + * either end. + */ + sz0 = sz1 = minsz; + for (;;) { + + /* If output is to a terminal then display a spinner to keep humans + * amused. + */ + if (spin >= 0) { + printf("\r%s: [%c]\b\b", name, spinner[spin]); fflush(stdout); + spin = (spin + 1)&3; + } + + /* Prepare for the test. */ + sz2 = TEXTSZ - sz1 - sz0; + ok = 1; + + /* Encrypt the last fragment first, to check discarding behaviour. */ + if (sz2) { + reset(iv); + enc(text, 0, sz0); + enc(text + sz0, 0, sz1); + enc(text + sz0 + sz1, ct + sz0 + sz1, sz2); + } + + /* Encrypt the first two fragments. */ + reset(iv); + enc(text, ct, sz0); + if (sz1) { + memcpy(ct + sz0, text + sz0, sz1); + enc(ct + sz0, ct + sz0, sz1); + } + + /* Try to check consistency. We can't do this if (a) the mode is + * non-resumable and the fragments sizes are misaligned, or (b) this is + * our first pass through and we don't have a consistency reference yet. + * + * Also, decide whether to deploy the regression test, which we do if and + * only if we can't compare against the consistency reference. + */ + regr = 0; + if ((f&TEMF_REFALIGN) && (sz0%blksz || sz1%blksz)) regr = 1; + else if (!refp) { memcpy(ref, ct, TEXTSZ); regr = 1; refp = 1; } + else if (memcmp(ref, ct, TEXTSZ) != 0) { + ok = 0; + printf("\nConsistency failure (split = %lu/%lu/%lu)\n", + (unsigned long)sz0, (unsigned long)sz1, (unsigned long)sz2); + dump_split("plaintext", blksz, text, sz0, sz1, sz2); + dump_split("reference", blksz, ref, sz0, sz1, sz2); + dump_split("ciphertext", blksz, ct, sz0, sz1, sz2); + fputc('\n', stdout); + } + + /* If we need the regression test then do that. Write a framing record + * to avoid confusion if the policy changes. + */ + if (regr) { + DRESET(&d); + dstr_putf(&d, "split = %lu/%lu/%lu", + (unsigned long)sz0, (unsigned long)sz1, (unsigned long)sz2); + regress_framing(rmode, fp, "split", d.buf, d.len); + if (regress_crypto(rmode, fp, "regress", blksz, ct, sz0, sz1, sz2)) + ok = 0; + } + + /* Finally, decrypt and check that the round-trip works. */ + reset(iv); + dec(ct, pt, sz0); + if (sz1) { + memcpy(pt + sz0, ct + sz0, sz1); + dec(pt + sz0, pt + sz0, sz1); + } + if (sz2) + dec(ct + sz0 + sz1, pt + sz0 + sz1, sz2); + if (memcmp(text, pt, TEXTSZ) != 0) { + ok = 0; + printf("\nRound-trip failure (split = %lu/%lu/%lu)\n", + (unsigned long)sz0, (unsigned long)sz1, (unsigned long)sz2); + dump_split("plaintext", blksz, text, sz0, sz1, sz2); + dump_split("ciphertext", blksz, ct, sz0, sz1, sz2); + dump_split("recovered", blksz, pt, sz0, sz1, sz2); + fputc('\n', stdout); + } + + /* Update the fragment sizes. */ + if (!sz1) break; + if (step(&sz1, TEXTSZ - sz0) == RESET) { + if (step(&sz0, TEXTSZ) == LIMIT) sz1 = 0; + else sz1 = minsz; + } + } + + /* Close the regression data file. */ + if (fp && (ferror(fp) || fclose(fp))) + die(1, "error closing `%s': %s", rname, strerror(errno)); + + /* Finish off the eyecandy spinner. */ + if (spin >= 0) printf("\r%s: [%c] ", name, ok ? '*' : 'X'); + + /* Summarize the test result. */ + if (ok) printf("ok\n"); + else printf("failed\n"); + + /* And we're done. */ + dstr_destroy(&d); + return (!ok); +} + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/symm/modes-test.h b/symm/modes-test.h new file mode 100644 index 00000000..83d35dc3 --- /dev/null +++ b/symm/modes-test.h @@ -0,0 +1,166 @@ +/* -*-c-*- + * + * Common testing for encryption modes + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef CATACOMB_MODES_TEST_H +#define CATACOMB_MODES_TEST_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +/*----- Data structures ---------------------------------------------------*/ + +/* Functions used by `test_encmode' below. */ +typedef void setupfn(const octet */*k*/, size_t /*ksz*/); +typedef void resetfn(const octet */*iv*/); +typedef void encfn(const octet */*s*/, octet */*d*/, size_t /*sz*/); + +/*----- Functions provided ------------------------------------------------*/ + +#define TEMF_REFALIGN 1u /* misalignment of pieces affects + * the encryption state + */ + +/* --- @test_encmode@ --- * + * + * Arguments: @const char *name@ = name of the encryption scheme; used to + * find the regression-test filename + * @size_t ksz@ = key size to use, or zero for `don't care' + * @size_t blksz@ = block size + * @size_t minsz@ = smallest acceptable buffer size, or 1 + * @unsigned f@ = various additional flags + * @setupfn *setup@ = key-setup function + * @resetfn *reset@ = state-reset function + * @encfn *enc@ = encryption function + * @decfn *dec@ = decryption function + * @int argc@ = number of command-line arguments + * @char *argv@ = pointer to command-line argument vector + * + * Returns: Zero on success, nonzero to report failure. + * + * Use: Tests an encryption mode which doesn't have any more formal + * test vectors. + * + * The @name@ is used firstly in diagnostic output and secondly + * to form the default filename to use for regression-test data, + * as `.../symm/t/modes/NAME.regress'. + * + * The key size @ksz@ is simply passed on back to the @setup@ + * function, unless the caller passes in zero, in which case + * @test_encmode@ chooses a key size for itself. + * + * The block size @blksz@ is used in failure reports, to draw + * attention to the block structure in the various buffers, + * which may assist with diagnosis. It's also used to determine + * when to apply a consistency check: see below regarding the + * @TEMF_REFALIGN@ flag. + * + * The minimum buffer size @minsz@ expresses a limitation on the + * provided @enc@ and @dec@ functions, that they don't work on + * inputs smaller than @minsz@; accordingly, @test_encmode@ will + * not test such small sizes. This should be 1 if the mode has + * no limitation. + * + * The flags @f@ influence testing in various ways explained + * below. + * + * The caller-provided functions are assumed to act on some + * global but hidden state, + * + * * @setup@ is (currently, at least) called only once, with + * the key @k@ and its chosen size @ksz@. + * + * * @reset@ is called at the start of each encryption or + * decryption operation, to program in the initialization + * vector to use. Currently, the same IV is used in all of + * the tests, but this might not always be the case. + * + * * @enc@ is called to encrypt a source buffer @s@ and write + * the ciphertext to a destination @d@; @sz@ is the common + * size of these buffers. @d@ might be null, to discard + * output; @s@ might be null, to process all-zero input. + * + * * @dec@ is called to decrypt a source buffer @s@ and write + * the recovered plaintext to a destination @d@; @sz@ is the + * common size of these buffers. + * + * Finally, @int argc@ and @char *argv@ are the command-line + * arguments provided to @main@; @test_encmode@ parses these and + * alters its behaviour accordingly. + * + * Currently, @test_encmode@'s tests are built around a single, + * fairly large, fixed message. In each test step, the message + * is split into a number of fragments which are encrypted and + * decrypted in turn. + * + * The following tests are performed. + * + * * The fundamental `round-trip' test, which verifies that + * the message can be encrypted and then decrypted + * successfully, if the same fragment boundaries are used in + * both cases. + * + * * A `consistency' test. Some modes, such as CFB, OFB, and + * counter, are `resumable': encryption operations are + * insensitive to the position of fragment boundaries, so a + * single message can be broken into fragments without + * affecting the result. If @TEMF_REFALIGN@ is clear then + * the mode under test is verified to have this property. + * If @TEMF_REFALIGN' is set, a weaker property is verified: + * that encryption is insensitive to the position of + * /block-aligned/ fragment boundaries only. + * + * * A `regression' test, which verifies that the code + * produces the same ciphertext as a previous version. By + * setting command-line arguments appropriately, a test + * program can be told to record ciphertexts in a (binary) + * data file. Usually, instead, the program will read the + * recorded ciphertexts back and verify that it produces the + * same data. For resumable modes, it's only necessary to + * record single ciphertext, since all the other ciphertexts + * must be equal by consistency; otherwise all non-block- + * aligned splits are recorded separately. + */ + +extern int test_encmode(const char */*name*/, + size_t /*ksz*/, size_t /*blksz*/, + size_t /*minsz */, unsigned /*f*/, + setupfn */*setup*/, resetfn */*reset*/, + encfn */*enc*/, encfn */*dec*/, + int /*argc*/, char */*argv*/[]); + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/modes.am.in b/symm/modes.am.in index 395d06f7..d95a5f1c 100644 --- a/symm/modes.am.in +++ b/symm/modes.am.in @@ -61,9 +61,18 @@ CIPHER_MODES += @{blkc:f}-@blkcciphermode CIPHER_MODES += @{hash:f}-@hashciphermode %end +## Modes for authenticated encryption. +AEAD_MODES = +%repeat +AEAD_MODES += @{blkc:f}-@blkcaeadmode +%end + ## Modes for message authentication. MAC_MODES = %repeat +MAC_MODES += @{blkc:f}-@blkcmacmode +%end +%repeat MAC_MODES += @{hash:f}-@hashmacmode %end @@ -75,3 +84,12 @@ SYMM_TEST_FILES += t/@{blkc:f} %repeat SYMM_TEST_FILES += t/@{hash:f} %end + +## Regression-test files. +REGRESSION_TEST_FILES = +%repeat +REGRESSION_TEST_FILES += t/modes/@{blkc:f}-@{blkcciphermode}.regress +%end +%repeat +REGRESSION_TEST_FILES += t/modes/@{hash:f}-@{hashciphermode}.regress +%end diff --git a/symm/ocb.c b/symm/ocb.c new file mode 100644 index 00000000..1c97215b --- /dev/null +++ b/symm/ocb.c @@ -0,0 +1,73 @@ +/* -*-c-*- + * + * Common definitions for OCB and related modes + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "config.h" + +#include "ocb.h" + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @ocb_ctz@, @ocb_ctzl@ --- * + * + * Arguments: @unsigned i@ or @unsigned long i@ = operand, assumed nonzero + * + * Returns: The number of trailing zero bits in @i@, or nonsense if + * %$i = 0$%. + */ + +unsigned ocb_ctz(unsigned i) +{ + unsigned n = 0; + + if (!(i&0x00ff)) { n += 8; i >>= 8; } + if (!(i&0x000f)) { n += 4; i >>= 4; } + if (!(i&0x0003)) { n += 2; i >>= 2; } + if (!(i&0x0001)) { n += 1; i >>= 1; } + return (n); +} + +unsigned ocb_ctzl(unsigned long i) +{ + unsigned n = 0; + +#if ULONG_BITS > 64 + while (!(i&0xfffffffffffffffful)) { n += 64; i >>= 64; } +#endif +#if ULONG_BITS > 32 + if (!(i&0xffffffff)) { n += 32; i >>= 32; } +#endif + if (!(i&0xffff)) { n += 16; i >>= 16; } + if (!(i&0x00ff)) { n += 8; i >>= 8; } + if (!(i&0x000f)) { n += 4; i >>= 4; } + if (!(i&0x0003)) { n += 2; i >>= 2; } + if (!(i&0x0001)) { n += 1; i >>= 1; } + return (n); +} + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/symm/ocb.h b/symm/ocb.h new file mode 100644 index 00000000..d87aed35 --- /dev/null +++ b/symm/ocb.h @@ -0,0 +1,117 @@ +/* -*-c-*- + * + * Common definitions for OCB and related modes + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef CATACOMB_OCB_H +#define CATACOMB_OCB_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +/*----- Constants ---------------------------------------------------------*/ + +/* The number of offsets to maintain. Rather than calculate and store all + * possible offset values in advance, or calculate new ones on demand (and + * have to allocate space for them), we calculate a number in advance, and + * determine any others every time they're needed. If we calculate the first + * %$n$% offsets only, then we spend %$i - n + 1$% time calculating offset + * %$L_i$% when %$i \ge n$%. But the offset %$L_i$% is used only for a + * %$2^{-i-1}$% fraction of the blocks. Summing up this geometric series + * shows us that we add only a small constant overhead, and save storage + * space for many offsets. + */ +#define OCB_NCALC 16 +#define OCB_CALCMASK ((1ul << OCB_NCALC) - 1) + +/*----- Functions provided ------------------------------------------------*/ + +/* --- @ocb_ctz@, @ocb_ctzl@ --- * + * + * Arguments: @unsigned i@ or @unsigned long i@ = operand, assumed nonzero + * + * Returns: The number of trailing zero bits in @i@, or nonsense if + * %$i = 0$%. + */ + +extern unsigned ocb_ctz(unsigned /*i*/); +extern unsigned ocb_ctzl(unsigned long /*i*/); + +#if GCC_VERSION_P(3, 4) +# define OCB_CTZ(i) __builtin_ctz(i) +# define OCB_CTZL(i) __builtin_ctzl(i) +#else +# define OCB_CTZ(i) ocb_ctz(i) +# define OCB_CTZL(i) ocb_ctzl(i) +#endif + +/* --- @OCB_OFFSET@ --- * + * + * Arguments: @PRE@ = block cipher prefix + * @uint32 *o@ = pointer to offset accumulator + * @uint32 (*l)[PRE_BLKSZ]@ = pointer to offset mask table + * @unsigned long i@ = block index + * + * Returns: --- + * + * Use: Update the per-block offset for Grey-code-based OCB + * variants. On entry, @o@ is assumed to hold the offset for + * block @i - 1@; on exit @o@ is updated to hold the offset for + * block @i@. + */ + +#define OCB_OFFSET(PRE, o, l, i) do { \ + uint32 (*_l)[PRE##_BLKSZ/4] = (l); \ + uint32 *_o = (o); \ + unsigned long _i = (i); \ + unsigned _j; \ + \ + if (_i&OCB_CALCMASK) { \ + _j = OCB_CTZ(_i); \ + BLKC_XMOVE(PRE, _o, _l[_j]); \ + } else { \ + uint32 _t[PRE##_BLKSZ]; \ + _j = OCB_CTZL(_i) - OCB_NCALC; \ + BLKC_BLSHIFT(PRE, IRRED, _t, _l[OCB_NCALC - 1]); \ + while (_j--) BLKC_BLSHIFT(PRE, IRRED, _t, _t); \ + BLKC_XMOVE(PRE, _t, _l[_j]); \ + } \ +} while (0) + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/ocb1-def.h b/symm/ocb1-def.h new file mode 100644 index 00000000..7c7eb295 --- /dev/null +++ b/symm/ocb1-def.h @@ -0,0 +1,670 @@ +/* -*-c-*- + * + * The OCB1 authenticated encryption mode + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef CATACOMB_OCB1_DEF_H +#define CATACOMB_OCB1_DEF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +#ifndef CATACOMB_ARENA_H +# include "arena.h" +#endif + +#ifndef CATACOMB_BLKC_H +# include "blkc.h" +#endif + +#ifndef CATACOMB_CT_H +# include "ct.h" +#endif + +#ifndef CATACOMB_KEYSZ_H +# include "keysz.h" +#endif + +#ifndef CATACOMB_PARANOIA_H +# include "paranoia.h" +#endif + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @OCB1_DEF@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates an implementation for the OCB1 authenticated- + * encryption mode. + */ + +#define OCB1_DEF(PRE, pre) OCB1_DEFX(PRE, pre, #pre, #pre) + +#define OCB1_DEFX(PRE, pre, name, fname) \ + \ +const octet \ + pre##_ocb1noncesz[] = { KSZ_SET, PRE##_BLKSZ, 0 }, \ + pre##_ocb1tagsz[] = { KSZ_RANGE, PRE##_BLKSZ, 0, PRE##_BLKSZ, 1 }; \ + \ +/* --- @pre_ocb1init@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to OCB1 context \ + * @const pre_ocb1key *key@ = pointer to key block \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: Zero on success, @-1@ if the nonce length is bad. \ + * \ + * Use: Initialize an OCB1 operation context with a given key. \ + * \ + * The original key needn't be kept around any more. \ + */ \ + \ +int pre##_ocb1init(pre##_ocb1ctx *ctx, const pre##_ocb1key *k, \ + const void *n, size_t nsz) \ + { ctx->k = *k; return (pre##_ocb1reinit(ctx, n, nsz)); } \ + \ +/* --- @pre_ocb1reinit@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to OCB1 context \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: Zero on success, @-1@ if the nonce length is bad. \ + * \ + * Use: Reinitialize an OCB1 operation context, changing the \ + * nonce. \ + */ \ + \ +int pre##_ocb1reinit(pre##_ocb1ctx *ctx, const void *n, size_t nsz) \ +{ \ + if (nsz != PRE##_BLKSZ) return (-1); \ + ctx->off = 0; BLKC_ZERO(PRE, ctx->a); \ + BLKC_LOAD(PRE, ctx->o, n); BLKC_XMOVE(PRE, ctx->o, ctx->k.lmask[0]); \ + pre##_eblk(&ctx->k.ctx, ctx->o, ctx->o); ctx->i = 1; \ + return (0); \ +} \ + \ +/* --- @pre_ocb1encrypt@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to OCB1 operation context \ + * @const void *src@ = pointer to plaintext message chunk \ + * @size_t sz@ = size of the plaintext \ + * @buf *dst@ = a buffer to write the ciphertext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Encrypts a chunk of a plaintext message, writing a \ + * chunk of ciphertext to the output buffer and updating \ + * the operation state. \ + * \ + * Note that OCB1 delays output if its input is not a \ + * whole number of blocks. This means that the output \ + * might be smaller or larger the input by up to the block \ + * size. \ + */ \ + \ +int pre##_ocb1encrypt(pre##_ocb1ctx *ctx, \ + const void *src, size_t sz, buf *dst) \ +{ \ + rsvr_state st; \ + size_t osz; \ + uint32 t[PRE##_BLKSZ/4]; \ + const octet *p; \ + octet *q; \ + \ + /* Figure out what we're going to do. */ \ + rsvr_setup(&st, &pre##_ocb1policy, ctx->b, &ctx->off, src, sz); \ + \ + /* Determine the output size and verify that there is enough \ + * space. \ + */ \ + osz = st.plan.from_rsvr + st.plan.from_input; \ + if (!osz) q = 0; \ + else { q = buf_get(dst, osz); if (!q) return (-1); } \ + \ + /* Process the input in whole blocks at a time. */ \ + RSVR_DO(&st) while ((p = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \ + OCB_OFFSET(PRE, ctx->o, ctx->k.lmask, ctx->i++); \ + BLKC_LOAD(PRE, t, p); BLKC_XMOVE(PRE, ctx->a, t); \ + BLKC_XMOVE(PRE, t, ctx->o); pre##_eblk(&ctx->k.ctx, t, t); \ + BLKC_XSTORE(PRE, q, t, ctx->o); q += PRE##_BLKSZ; \ + } \ + \ + /* Done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ocb1decrypt@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to OCB1 operation context \ + * @const void *src@ = pointer to ciphertext message chunk \ + * @size_t sz@ = size of the ciphertext \ + * @buf *dst@ = a buffer to write the plaintext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Decrypts a chunk of a ciphertext message, writing a \ + * chunk of plaintext to the output buffer and updating \ + * the operation state. \ + * \ + * Note that OCB1 delays output if its input is not a \ + * whole number of blocks. This means that the output \ + * might be smaller or larger the input by up to the block \ + * size. \ + */ \ + \ +int pre##_ocb1decrypt(pre##_ocb1ctx *ctx, \ + const void *src, size_t sz, buf *dst) \ +{ \ + rsvr_state st; \ + size_t osz; \ + uint32 t[PRE##_BLKSZ/4]; \ + const octet *p; \ + octet *q; \ + \ + /* Figure out what we're going to do. */ \ + rsvr_setup(&st, &pre##_ocb1policy, ctx->b, &ctx->off, src, sz); \ + \ + /* Determine the output size and verify that there is enough \ + * space. \ + */ \ + osz = st.plan.from_rsvr + st.plan.from_input; \ + if (!osz) q = 0; \ + else { q = buf_get(dst, osz); if (!q) return (-1); } \ + \ + /* Process the input in whole blocks at a time. */ \ + RSVR_DO(&st) while ((p = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \ + OCB_OFFSET(PRE, ctx->o, ctx->k.lmask, ctx->i++); \ + BLKC_LOAD(PRE, t, p); \ + BLKC_XMOVE(PRE, t, ctx->o); pre##_dblk(&ctx->k.ctx, t, t); \ + BLKC_XMOVE(PRE, t, ctx->o); BLKC_XMOVE(PRE, ctx->a, t); \ + BLKC_STORE(PRE, q, t); q += PRE##_BLKSZ; \ + } \ + \ + /* Done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ocb1encdecfinal@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to an OCB1 context \ + * @const pre_ocb1aadctx *aad@ = pointer to AAD context, \ + * or null \ + * @buf *dst@ = buffer for remaining ciphertext \ + * @int encp@ = nonzero if we're encrypting \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Common end-of-message handling for encryption and \ + * decryption. The full-length tag is left in the \ + * context's buffer. \ + */ \ + \ +static int pre##_ocb1encdecfinal(pre##_ocb1ctx *ctx, \ + const pre##_ocb1aadctx *aad, buf *dst, \ + int encp) \ +{ \ + octet *q; \ + \ + /* Arrange space for the final output (if any). */ \ + if (!ctx->off) { q = 0; if (!BOK(dst)) return (-1); } \ + else { q = buf_get(dst, ctx->off); if (!q) return (-1); } \ + \ + /* Calculate the final offset. Mix it into the checksum before it \ + * gets clobbered. \ + */ \ + OCB_OFFSET(PRE, ctx->o, ctx->k.lmask, ctx->i++); \ + BLKC_XMOVE(PRE, ctx->a, ctx->o); \ + \ + /* Mix the magic final mask and tail length into the offset. */ \ + BLKC_XMOVE(PRE, ctx->o, ctx->k.lxinv); \ + ctx->o[PRE##_BLKSZ/4 - 1] ^= BLKC_BWORD(PRE, 8*ctx->off); \ + \ + /* If we're decrypting, then trim the end of the plaintext and fold \ + * that into the checksum. \ + */ \ + if (!encp) { \ + memset(ctx->b + ctx->off, 0, PRE##_BLKSZ - ctx->off); \ + BLKC_XLOAD(PRE, ctx->a, ctx->b); \ + } \ + \ + /* Cycle the block cipher for the last plaintext block. */ \ + pre##_eblk(&ctx->k.ctx, ctx->o, ctx->o); \ + \ + /* Fold this mask into the checksum before it gets clobbered. */ \ + BLKC_XMOVE(PRE, ctx->a, ctx->o); \ + \ + /* Encrypt the message tail. */ \ + BLKC_XLOAD(PRE, ctx->o, ctx->b); \ + BLKC_STORE(PRE, ctx->b, ctx->o); \ + if (ctx->off) memcpy(q, ctx->b, ctx->off); \ + \ + /* If we're encrypting, then trim the end of the ciphertext and fold \ + * that into the checksum. \ + */ \ + if (encp) { \ + memset(ctx->b + ctx->off, 0, PRE##_BLKSZ - ctx->off); \ + BLKC_XLOAD(PRE, ctx->a, ctx->b); \ + } \ + \ + /* Encrypt the checksum to produce a tag. */ \ + pre##_eblk(&ctx->k.ctx, ctx->a, ctx->a); \ + \ + /* If there's AAD then mix the PMAC tag in too. */ \ + if (aad && aad->off) \ + { pre##_ocb1aadtag(aad, ctx->o); BLKC_XMOVE(PRE, ctx->a, ctx->o); } \ + \ + /* Write the final tag. */ \ + BLKC_STORE(PRE, ctx->b, ctx->a); \ + \ + /* Done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ocb1encryptdone@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to an OCB1 context \ + * @const pre_ocb1aadctx *aad@ = pointer to AAD context, \ + * or null \ + * @buf *dst@ = buffer for remaining ciphertext \ + * @void *tag@ = where to write the tag \ + * @size_t tsz@ = length of tag to store \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Completes an OCB1 encryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. OCB1 delays output, so this will \ + * cause any remaining buffered plaintext to be encrypted \ + * and written to @dst@. Anyway, the function will fail \ + * if the output buffer is broken. \ + */ \ + \ +int pre##_ocb1encryptdone(pre##_ocb1ctx *ctx, \ + const pre##_ocb1aadctx *aad, buf *dst, \ + void *tag, size_t tsz) \ +{ \ + assert(tsz <= PRE##_BLKSZ); \ + if (pre##_ocb1encdecfinal(ctx, aad, dst, 1)) return (-1); \ + memcpy(tag, ctx->b, tsz); \ + return (0); \ +} \ + \ +/* --- @pre_ocb1decryptdone@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to an OCB1 context \ + * @const pre_ocb1aadctx *aad@ = pointer to AAD context, \ + * or null \ + * @buf *dst@ = buffer for remaining plaintext \ + * @const void *tag@ = tag to verify \ + * @size_t tsz@ = length of tag \ + * \ + * Returns: @+1@ for complete success; @0@ if tag verification \ + * failed; @-1@ for other kinds of errors. \ + * \ + * Use: Completes an OCB1 decryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. OCB1 delays output, so this will \ + * cause any remaining buffered ciphertext to be decrypted \ + * and written to @dst@. Anyway, the function will fail \ + * if the output buffer is broken. \ + */ \ + \ +int pre##_ocb1decryptdone(pre##_ocb1ctx *ctx, \ + const pre##_ocb1aadctx *aad, buf *dst, \ + const void *tag, size_t tsz) \ +{ \ + assert(tsz <= PRE##_BLKSZ); \ + if (pre##_ocb1encdecfinal(ctx, aad, dst, 0)) return (-1); \ + else if (ct_memeq(tag, ctx->b, tsz)) return (+1); \ + else return (0); \ +} \ + \ +/* --- Generic AEAD interface --- */ \ + \ +typedef struct gactx { \ + gaead_aad a; \ + pre##_ocb1aadctx aad; \ +} gactx; \ + \ +static gaead_aad *gadup(const gaead_aad *a) \ + { gactx *aad = S_CREATE(gactx); *aad = *(gactx *)a; return (&aad->a); } \ + \ +static void gahash(gaead_aad *a, const void *h, size_t hsz) \ + { gactx *aad = (gactx *)a; pre##_ocb1aadhash(&aad->aad, h, hsz); } \ + \ +static void gadestroy(gaead_aad *a) \ + { gactx *aad = (gactx *)a; BURN(*aad); S_DESTROY(aad); } \ + \ +static const gaead_aadops gaops = \ + { &pre##_ocb1, gadup, gahash, gadestroy }; \ + \ +static gaead_aad *gaad(const pre##_ocb1key *k) \ +{ \ + gactx *aad = S_CREATE(gactx); \ + aad->a.ops = &gaops; \ + pre##_ocb1aadinit(&aad->aad, k); \ + return (&aad->a); \ +} \ + \ +typedef struct gectx { \ + gaead_enc e; \ + pre##_ocb1ctx ctx; \ +} gectx; \ + \ +static gaead_aad *geaad(gaead_enc *e) \ + { gectx *enc = (gectx *)e; return (gaad(&enc->ctx.k)); } \ + \ +static int gereinit(gaead_enc *e, const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gectx *enc = (gectx *)e; \ + return (pre##_ocb1reinit(&enc->ctx, n, nsz)); \ +} \ + \ +static int geenc(gaead_enc *e, const void *m, size_t msz, buf *b) \ +{ \ + gectx *enc = (gectx *)e; \ + return (pre##_ocb1encrypt(&enc->ctx, m, msz, b)); \ +} \ + \ +static int gedone(gaead_enc *e, const gaead_aad *a, \ + buf *b, void *t, size_t tsz) \ +{ \ + gectx *enc = (gectx *)e; gactx *aad = (gactx *)a; \ + assert(!a || a->ops == &gaops); \ + return (pre##_ocb1encryptdone(&enc->ctx, a ? &aad->aad : 0, b, t, tsz)); \ +} \ + \ +static void gedestroy(gaead_enc *e) \ + { gectx *enc = (gectx *)e; BURN(*enc); S_DESTROY(enc); } \ + \ +static const gaead_encops geops = \ + { &pre##_ocb1, geaad, gereinit, geenc, gedone, gedestroy }; \ + \ +typedef struct gdctx { \ + gaead_dec d; \ + pre##_ocb1ctx ctx; \ +} gdctx; \ + \ +static gaead_aad *gdaad(gaead_dec *d) \ + { gdctx *dec = (gdctx *)d; return (gaad(&dec->ctx.k)); } \ + \ +static int gdreinit(gaead_dec *d, const void *n, size_t nsz, \ + size_t hsz, size_t csz, size_t tsz) \ +{ \ + gdctx *dec = (gdctx *)d; \ + return (pre##_ocb1reinit(&dec->ctx, n, nsz)); \ +} \ + \ +static int gddec(gaead_dec *d, const void *c, size_t csz, buf *b) \ +{ \ + gdctx *dec = (gdctx *)d; \ + return (pre##_ocb1decrypt(&dec->ctx, c, csz, b)); \ +} \ + \ +static int gddone(gaead_dec *d, const gaead_aad *a, \ + buf *b, const void *t, size_t tsz) \ +{ \ + gdctx *dec = (gdctx *)d; gactx *aad = (gactx *)a; \ + assert(!a || a->ops == &gaops); \ + return (pre##_ocb1decryptdone(&dec->ctx, a ? &aad->aad : 0, b, t, tsz)); \ +} \ + \ +static void gddestroy(gaead_dec *d) \ + { gdctx *dec = (gdctx *)d; BURN(*dec); S_DESTROY(dec); } \ + \ +static const gaead_decops gdops = \ + { &pre##_ocb1, gdaad, gdreinit, gddec, gddone, gddestroy }; \ + \ +typedef struct gkctx { \ + gaead_key k; \ + pre##_ocb1key key; \ +} gkctx; \ + \ +static gaead_aad *gkaad(const gaead_key *k) \ + { gkctx *key = (gkctx *)k; return (gaad(&key->key)); } \ + \ +static gaead_enc *gkenc(const gaead_key *k, const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gkctx *key = (gkctx *)k; \ + gectx *enc = S_CREATE(gectx); \ + \ + enc->e.ops = &geops; \ + if (pre##_ocb1init(&enc->ctx, &key->key, n, nsz)) \ + { gedestroy(&enc->e); return (0); } \ + return (&enc->e); \ +} \ + \ +static gaead_dec *gkdec(const gaead_key *k, const void *n, size_t nsz, \ + size_t hsz, size_t csz, size_t tsz) \ +{ \ + gkctx *key = (gkctx *)k; \ + gdctx *dec = S_CREATE(gdctx); \ + \ + dec->d.ops = &gdops; \ + if (pre##_ocb1init(&dec->ctx, &key->key, n, nsz)) \ + { gddestroy(&dec->d); return (0); } \ + return (&dec->d); \ +} \ + \ +static void gkdestroy(gaead_key *k) \ + { gkctx *key = (gkctx *)k; BURN(*key); S_DESTROY(key); } \ + \ +static const gaead_keyops gkops = \ + { &pre##_ocb1, gkaad, gkenc, gkdec, gkdestroy }; \ + \ +static gaead_key *gckey(const void *k, size_t ksz) \ +{ \ + gkctx *key = S_CREATE(gkctx); \ + key->k.ops = &gkops; \ + pre##_ocb1setkey(&key->key, k, ksz); \ + return (&key->k); \ +} \ + \ +const gcaead pre##_ocb1 = { \ + name "-ocb1", \ + pre##_keysz, pre##_ocb1noncesz, pre##_ocb1tagsz, \ + PRE##_BLKSZ, PRE##_BLKSZ, 0, 0, \ + gckey \ +}; \ + \ +OCB1_TESTX(PRE, pre, name, fname) + +/*----- Test rig ----------------------------------------------------------*/ + +#define OCB1_TEST(PRE, pre) OCB1_TESTX(PRE, pre, #pre, #pre) + +/* --- @OCB1_TEST@ --- * + * + * Arguments: @PRE, pre@ = prefixes for the underlying block cipher + * + * Use: Standard test rig for OCB1 functions. + */ + +#ifdef TEST_RIG + +#include + +#include +#include +#include + +#define OCB1_TESTX(PRE, pre, name, fname) \ + \ +static int ocb1verify(dstr *v) \ +{ \ + pre##_ocb1key key; \ + pre##_ocb1aadctx aad; \ + pre##_ocb1ctx ctx; \ + int ok = 1, win; \ + int i; \ + octet *p; \ + int szs[] = { 1, 7, 192, -1, 0 }, *ip; \ + size_t hsz, msz; \ + dstr d = DSTR_INIT, t = DSTR_INIT; \ + buf b; \ + \ + dstr_ensure(&d, v[4].len > v[3].len ? v[4].len : v[3].len); \ + dstr_ensure(&t, v[5].len); t.len = v[5].len; \ + \ + pre##_ocb1setkey(&key, v[0].buf, v[0].len); \ + \ + for (ip = szs; *ip; ip++) { \ + \ + pre##_ocb1init(&ctx, &key, (octet *)v[1].buf, v[1].len); \ + \ + i = *ip; \ + hsz = v[2].len; \ + if (i == -1) i = hsz; \ + if (i > hsz) continue; \ + p = (octet *)v[2].buf; \ + pre##_ocb1aadinit(&aad, &key); \ + while (hsz) { \ + if (i > hsz) i = hsz; \ + pre##_ocb1aadhash(&aad, p, i); \ + p += i; hsz -= i; \ + } \ + \ + buf_init(&b, d.buf, d.sz); \ + i = *ip; \ + msz = v[3].len; \ + if (i == -1) i = msz; \ + if (i > msz) continue; \ + p = (octet *)v[3].buf; \ + while (msz) { \ + if (i > msz) i = msz; \ + if (pre##_ocb1encrypt(&ctx, p, i, &b)) { \ + puts("!! ocb1encrypt reports failure"); \ + goto fail_enc; \ + } \ + p += i; msz -= i; \ + } \ + \ + if (pre##_ocb1encryptdone(&ctx, &aad, &b, (octet *)t.buf, t.len)) { \ + puts("!! ocb1encryptdone reports failure"); \ + goto fail_enc; \ + } \ + d.len = BLEN(&b); \ + \ + if (d.len != v[4].len || \ + memcmp(d.buf, v[4].buf, v[4].len) != 0 || \ + memcmp(t.buf, v[5].buf, v[5].len) != 0) { \ + fail_enc: \ + printf("\nfail encrypt:\n\tstep = %i", *ip); \ + fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \ + fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \ + fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \ + fputs("\n\tmessage = ", stdout); type_hex.dump(&v[3], stdout); \ + fputs("\n\texp ct = ", stdout); type_hex.dump(&v[4], stdout); \ + fputs("\n\tcalc ct = ", stdout); type_hex.dump(&d, stdout); \ + fputs("\n\texp tag = ", stdout); type_hex.dump(&v[5], stdout); \ + fputs("\n\tcalc tag = ", stdout); type_hex.dump(&t, stdout); \ + putchar('\n'); \ + ok = 0; \ + } \ + \ + pre##_ocb1init(&ctx, &key, (octet *)v[1].buf, v[1].len); \ + \ + buf_init(&b, d.buf, d.sz); \ + i = *ip; \ + msz = v[4].len; \ + if (i == -1) i = msz; \ + if (i > msz) continue; \ + p = (octet *)v[4].buf; \ + while (msz) { \ + if (i > msz) i = msz; \ + if (pre##_ocb1decrypt(&ctx, p, i, &b)) { \ + puts("!! ocb1decrypt reports failure"); \ + win = 0; goto fail_dec; \ + } \ + p += i; msz -= i; \ + } \ + \ + win = pre##_ocb1decryptdone(&ctx, &aad, &b, \ + (octet *)v[5].buf, v[5].len); \ + if (win < 0) { \ + puts("!! ocb1decryptdone reports failure"); \ + goto fail_dec; \ + } \ + d.len = BLEN(&b); \ + \ + if (d.len != v[3].len || !win || \ + memcmp(d.buf, v[3].buf, v[3].len) != 0) { \ + fail_dec: \ + printf("\nfail decrypt:\n\tstep = %i", *ip); \ + fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \ + fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \ + fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \ + fputs("\n\tciphertext = ", stdout); type_hex.dump(&v[4], stdout); \ + fputs("\n\texp pt = ", stdout); type_hex.dump(&v[3], stdout); \ + fputs("\n\tcalc pt = ", stdout); type_hex.dump(&d, stdout); \ + fputs("\n\ttag = ", stdout); type_hex.dump(&v[5], stdout); \ + printf("\n\tverify %s", win ? "ok" : "FAILED"); \ + putchar('\n'); \ + ok = 0; \ + } \ + } \ + \ + dstr_destroy(&d); dstr_destroy(&t); \ + return (ok); \ +} \ + \ +static test_chunk aeaddefs[] = { \ + { name "-ocb1", ocb1verify, \ + { &type_hex, &type_hex, &type_hex, &type_hex, \ + &type_hex, &type_hex, 0 } }, \ + { 0, 0, { 0 } } \ +}; \ + \ +int main(int argc, char *argv[]) \ +{ \ + ego(argv[0]); \ + test_run(argc, argv, aeaddefs, SRCDIR"/t/" fname); \ + return (0); \ +} + +#else +# define OCB1_TESTX(PRE, pre, name, fname) +#endif + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/ocb1.h b/symm/ocb1.h new file mode 100644 index 00000000..42cfb81b --- /dev/null +++ b/symm/ocb1.h @@ -0,0 +1,345 @@ +/* -*-c-*- + * + * The OCB1 authenticated encryption mode + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Notes on OCB1 -----------------------------------------------------* + * + * OCB was designed in 2001 by Phillip Rogaway, with Mihir Bellare and John + * Black, as a blockcipher-based authenticated encryption scheme which can + * operate on multiple message blocks in parallel and requires only a single + * blockcipher application per message block. It refines Charanjit Jutla's + * earlier IAPM, which was the first such mode to be proven secure. This + * version implements the `OCB.PMAC' mode described by Rogaway in 2002, which + * combines the original OCB with PMAC (Rogaway and Black, 2002) into a + * single authenticated-encryption with associated-data (AEAD) scheme. + * + * The patent situation on these efficient authenticated encryption schemes + * is fraught. IBM hold two patents on Jutla's pioneering work on `IACBC' + * and `IAPM' which can apply (a third was filed at least six years too + * late), and Virgil Gligor and Pompiliu Donescu hold patents on their `XECB' + * and `XCBC' modes; these may or may not apply to OCB. Rogaway himself + * holds US patents on various versions of OCB, but has issued free licences + * for free (`open source') software, and for all non-military use. I think + * Catacomb's implementation of OCB falls within the scope of the former + * licence. + * + * Confusingly, Rogaway's 2004 paper `Efficient Instantiations of Tweakable + * Blockciphers and Refinements to Modes OCB and PMAC' named the new versions + * of those modes `OCB1' and `PMAC1'. The 2011 paper by Krovetz and Rogaway, + * `The Software Performance of Authenticated-Encryption Modes' renamed the + * original 2001 version of OCB as `OCB1', and the 2004 version `OCB2', and + * introduced a new `OCB3'. I've decided to follow and extend the 2011 + * naming, so `OCB1' refers to the 2001 OCB; the 2004 version would be + * `OCB2'. + * + * The OCB specification is clear about how OCB applies to arbitrary block + * sizes. + * + * OCB1 is a fairly well-behaved AEAD mode. It doesn't require + * precommentment to any lengths, and allows header data to be processed + * independently of any message. On the other hand, it only accepts nonces + * the same size as the underlying blockcipher's block size, and it buffers + * up to a whole block's worth of data internally, which somewhat complicates + * streaming. + */ + +#ifndef CATACOMB_OCB1_H +#define CATACOMB_OCB1_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +#ifndef CATACOMB_GAEAD_H +# include "gaead.h" +#endif + +#ifndef CATACOMB_OCB_H +# include "ocb.h" +#endif + +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @OCB1_DECL@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates declarations for OCB1 message-authentication mode. + */ + +#define OCB1_STRUCTS(PRE, pre, keyty, aadty) \ + \ +typedef struct keyty { \ + pre##_ctx ctx; /* Underlying cipher context */ \ + uint32 lxinv[PRE##_BLKSZ/4]; /* Final-block mask */ \ + uint32 lmask[OCB_NCALC][PRE##_BLKSZ/4]; /* Precalculated masks */ \ +} keyty; \ + \ +typedef struct aadty { \ + keyty k; /* Processed key material */ \ + uint32 o[PRE##_BLKSZ/4]; /* Current offset */ \ + uint32 a[PRE##_BLKSZ/4]; /* Accumulator state */ \ + octet b[PRE##_BLKSZ]; /* Input buffer */ \ + unsigned long i; /* Block counter */ \ + unsigned off; /* Offset into buffered data */ \ +} aadty; + +#define OCB1_DECL(PRE, pre) \ + \ +OCB1_STRUCTS(PRE, pre, pre##_ocb1key, pre##_ocb1aadctx) \ + \ +typedef struct pre##_ocb1ctx { \ + /* This is the same as @pre_ocb1aadctx@ above, but the two are \ + * logically distinct and shouldn't be muddled up. \ + */ \ + \ + pre##_ocb1key k; /* Processed key material */ \ + uint32 o[PRE##_BLKSZ/4]; /* Current offset */ \ + uint32 a[PRE##_BLKSZ/4]; /* Accumulator state */ \ + octet b[PRE##_BLKSZ]; /* Input buffer */ \ + unsigned long i; /* Block counter */ \ + unsigned off; /* Offset into buffered data */ \ +} pre##_ocb1ctx; \ + \ +extern const rsvr_policy pre##_ocb1policy; \ + \ +extern const octet pre##_ocb1noncesz[], pre##_ocb1tagsz[]; \ + \ +/* --- @pre_ocb1setkey@ --- * \ + * \ + * Arguments: @pre_ocb1key *key@ = pointer to key block to fill in \ + * @const void *k@ = pointer to key material \ + * @size_t ksz@ = size of key material \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an OCB1 key block. \ + */ \ + \ +extern void pre##_ocb1setkey(pre##_ocb1key */*key*/, \ + const void */*k*/, size_t /*ksz*/); \ + \ +/* --- @pre_ocb1aadinit@ --- * \ + * \ + * Arguments: @pre_ocb1aadctx *aad@ = pointer to AAD context \ + * @const pre_ocb1key *key@ = pointer to key block \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an OCB1 AAD (`additional authenticated \ + * data') context associated with a given key. AAD \ + * contexts can be copied and/or reused, saving time if \ + * the AAD for number of messages has a common prefix. \ + * \ + * The @key@ doesn't need to be kept around, though \ + * usually there'll at least be another copy in some OCB1 \ + * operation context because the AAD on its own isn't much \ + * good. \ + */ \ + \ +extern void pre##_ocb1aadinit(pre##_ocb1aadctx */*aad*/, \ + const pre##_ocb1key */*key*/); \ + \ +/* --- @pre_ocb1aadhash@ --- * \ + * \ + * Arguments: @pre_ocb1aadctx *aad@ = pointer to AAD context \ + * @const void *p@ = pointer to AAD material \ + * @size_t sz@ = length of AAD material \ + * \ + * Returns: --- \ + * \ + * Use: Feeds AAD into the context. \ + */ \ + \ +extern void pre##_ocb1aadhash(pre##_ocb1aadctx */*aad*/, \ + const void */*p*/, size_t /*sz*/); \ + \ +/* --- @pre_ocb1aadtag@ --- * \ + * \ + * Arguments: @const pre_ocb1aadctx *aad@ = pointer to context block \ + * @uint32 *u@ = where to write the tag \ + * \ + * Returns: --- \ + * \ + * Use: Finishes processing AAD and produces a tag which can be \ + * mixed with an OCB1 checksum. This function is exposed \ + * for internal reasons and is not expected to be \ + * generally useful. \ + */ \ + \ +extern void pre##_ocb1aadtag(const pre##_ocb1aadctx */*aad*/, \ + uint32 */*t*/); \ + \ +/* --- @pre_ocb1init@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to OCB1 context \ + * @const pre_ocb1key *key@ = pointer to key block \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: Zero on success, @-1@ if the nonce length is bad. \ + * \ + * Use: Initialize an OCB1 operation context with a given key. \ + * \ + * The original key needn't be kept around any more. \ + */ \ + \ +extern int pre##_ocb1init(pre##_ocb1ctx */*ctx*/, \ + const pre##_ocb1key */*k*/, \ + const void */*n*/, size_t /*nsz*/); \ + \ +/* --- @pre_ocb1reinit@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to OCB1 context \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * \ + * Returns: Zero on success, @-1@ if the nonce length is bad. \ + * \ + * Use: Reinitialize an OCB1 operation context, changing the \ + * nonce. \ + */ \ + \ +extern int pre##_ocb1reinit(pre##_ocb1ctx */*ctx*/, \ + const void */*n*/, size_t /*nsz*/); \ + \ +/* --- @pre_ocb1encrypt@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to OCB1 operation context \ + * @const void *src@ = pointer to plaintext message chunk \ + * @size_t sz@ = size of the plaintext \ + * @buf *dst@ = a buffer to write the ciphertext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Encrypts a chunk of a plaintext message, writing a \ + * chunk of ciphertext to the output buffer and updating \ + * the operation state. \ + * \ + * Note that OCB1 delays output if its input is not a \ + * whole number of blocks. This means that the output \ + * might be smaller or larger the input by up to the block \ + * size. \ + */ \ + \ +extern int pre##_ocb1encrypt(pre##_ocb1ctx */*ctx*/, \ + const void */*src*/, size_t /*sz*/, \ + buf */*dst*/); \ + \ +/* --- @pre_ocb1decrypt@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to OCB1 operation context \ + * @const void *src@ = pointer to ciphertext message chunk \ + * @size_t sz@ = size of the ciphertext \ + * @buf *dst@ = a buffer to write the plaintext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Decrypts a chunk of a ciphertext message, writing a \ + * chunk of plaintext to the output buffer and updating \ + * the operation state. \ + * \ + * Note that OCB1 delays output if its input is not a \ + * whole number of blocks. This means that the output \ + * might be smaller or larger the input by up to the block \ + * size. \ + */ \ + \ +extern int pre##_ocb1decrypt(pre##_ocb1ctx */*ctx*/, \ + const void */*src*/, size_t /*sz*/, \ + buf */*dst*/); \ + \ +/* --- @pre_ocb1encryptdone@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to an OCB1 context \ + * @const pre_ocb1aadctx *aad@ = pointer to AAD context, \ + * or null \ + * @buf *dst@ = buffer for remaining ciphertext \ + * @void *tag@ = where to write the tag \ + * @size_t tsz@ = length of tag to store \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Completes an OCB1 encryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. OCB1 delays output, so this will \ + * cause any remaining buffered plaintext to be encrypted \ + * and written to @dst@. Anyway, the function will fail \ + * if the output buffer is broken. \ + */ \ + \ +extern int pre##_ocb1encryptdone(pre##_ocb1ctx */*ctx*/, \ + const pre##_ocb1aadctx */*aad*/, \ + buf */*dst*/, \ + void */*tag*/, size_t /*tsz*/); \ + \ +/* --- @pre_ocb1decryptdone@ --- * \ + * \ + * Arguments: @pre_ocb1ctx *ctx@ = pointer to an OCB1 context \ + * @const pre_ocb1aadctx *aad@ = pointer to AAD context, \ + * or null \ + * @buf *dst@ = buffer for remaining plaintext \ + * @const void *tag@ = tag to verify \ + * @size_t tsz@ = length of tag \ + * \ + * Returns: @+1@ for complete success; @0@ if tag verification \ + * failed; @-1@ for other kinds of errors. \ + * \ + * Use: Completes an OCB1 decryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. OCB1 delays output, so this will \ + * cause any remaining buffered ciphertext to be decrypted \ + * and written to @dst@. Anyway, the function will fail \ + * if the output buffer is broken. \ + */ \ + \ +extern int pre##_ocb1decryptdone(pre##_ocb1ctx */*ctx*/, \ + const pre##_ocb1aadctx */*aad*/, \ + buf */*dst*/, \ + const void */*tag*/, size_t /*tsz*/); \ + \ +/* --- Generic AEAD interface --- */ \ + \ +extern const gcaead pre##_ocb1; + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/ocb3-def.h b/symm/ocb3-def.h new file mode 100644 index 00000000..14a22f61 --- /dev/null +++ b/symm/ocb3-def.h @@ -0,0 +1,1006 @@ +/* -*-c-*- + * + * The OCB3 authenticated encryption mode + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef CATACOMB_OCB3_DEF_H +#define CATACOMB_OCB3_DEF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +#ifndef CATACOMB_ARENA_H +# include "arena.h" +#endif + +#ifndef CATACOMB_BLKC_H +# include "blkc.h" +#endif + +#ifndef CATACOMB_CT_H +# include "ct.h" +#endif + +#ifndef CATACOMB_KEYSZ_H +# include "keysz.h" +#endif + +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + +#ifndef CATACOMB_PARANOIA_H +# include "paranoia.h" +#endif + +/*----- Macros ------------------------------------------------------------*/ + +#define OCB3_TSHIFT(PRE) BLKC_GLUE(OCB3_TSHIFT_, BLKC_BITS(PRE)) +#define OCB3_TSHIFT_64 2 +#define OCB3_TSHIFT_96 1 +#define OCB3_TSHIFT_128 1 +#define OCB3_TSHIFT_192 0 +#define OCB3_TSHIFT_256 0 + +#define OCB3_STRETCHMASK(PRE) BLKC_GLUE(OCB3_STRETCHMASK_, BLKC_BITS(PRE)) +#define OCB3_STRETCHMASK_64 0x1f +#define OCB3_STRETCHMASK_96 0x3f +#define OCB3_STRETCHMASK_128 0x3f +#define OCB3_STRETCHMASK_192 0x7f +#define OCB3_STRETCHMASK_256 0xff + +#define OCB3_STRETCHSHIFT(PRE) BLKC_GLUE(OCB3_STRETCHSHIFT_, BLKC_BITS(PRE)) +#define OCB3_STRETCHSHIFT_64 25 +#define OCB3_STRETCHSHIFT_96 33 +#define OCB3_STRETCHSHIFT_128 8 +#define OCB3_STRETCHSHIFT_192 40 +#define OCB3_STRETCHSHIFT_256 1 + +/* --- @OCB3_DEF@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates an implementation for the OCB3 authenticated- + * encryption mode. + */ + +#define OCB3_DEF(PRE, pre) OCB3_DEFX(PRE, pre, #pre, #pre) + +#define OCB3_DEFX(PRE, pre, name, fname) \ + \ +static const rsvr_policy pre##_ocb3policy = \ + { 0, PRE##_BLKSZ, PRE##_BLKSZ }; \ + \ +const octet \ + pre##_ocb3noncesz[] = { KSZ_RANGE, OCB3_NSZMAX(PRE), \ + 0, OCB3_NSZMAX(PRE), 1 }, \ + pre##_ocb3tagsz[] = { KSZ_RANGE, PRE##_BLKSZ, 0, PRE##_BLKSZ, 1 }; \ + \ +/* --- @pre_ocb3setkey@ --- * \ + * \ + * Arguments: @pre_ocb3key *key@ = pointer to OCB3 key block \ + * @ocnst void *k@ = pointer to key material \ + * @size_t ksz@ = size of key material \ + * \ + * Returns: --- \ + * \ + * Use: Initializes a OCB3 key. This can be used for \ + * several encryption/or MAC operations. \ + */ \ + \ +void pre##_ocb3setkey(pre##_ocb3key *key, const void *k, size_t ksz) \ +{ \ + unsigned i; \ + \ + pre##_init(&key->ctx, k, ksz); \ + BLKC_ZERO(PRE, key->lstar); \ + pre##_eblk(&key->ctx, key->lstar, key->lstar); \ + BLKC_BLSHIFT(PRE, IRRED, key->ldollar, key->lstar); \ + BLKC_BLSHIFT(PRE, IRRED, key->lmask[0], key->ldollar); \ + for (i = 1; i < OCB_NCALC; i++) \ + BLKC_BLSHIFT(PRE, IRRED, key->lmask[i], key->lmask[i - 1]); \ +} \ + \ +/* --- @pre_ocb3aadinit@ --- * \ + * \ + * Arguments: @pre_ocb3aadctx *aad@ = pointer to context block \ + * @pre_ocb3key *k@ = key block \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an OCB3 AAD (`additional authenticated \ + * data') context associated witha a given key. \ + * AAD contexts can be copied and/or reused, saving time \ + * if the AAD for a number of messages has a common \ + * prefix. \ + * \ + * The @key@ doesn't need to be kept around. \ + */ \ + \ +void pre##_ocb3aadinit(pre##_ocb3aadctx *aad, const pre##_ocb3key *k) \ +{ \ + aad->k = *k; \ + aad->off = 0; aad->i = 1; \ + BLKC_ZERO(PRE, aad->a); \ + BLKC_ZERO(PRE, aad->o); \ +} \ + \ +/* --- @pre_ocb3aadhash@ --- * \ + * \ + * Arguments: @pre_ocb3aadctx *aad@ = pointer to context block \ + * @ocnst void *p@ = pointer to message buffer \ + * @size_t sz@ = size of message buffer \ + * \ + * Returns: --- \ + * \ + * Use: Hashes some AAD input data. \ + */ \ + \ +void pre##_ocb3aadhash(pre##_ocb3aadctx *aad, const void *p, size_t sz) \ +{ \ + rsvr_state st; \ + uint32 t[PRE##_BLKSZ/4]; \ + const octet *q; \ + \ + rsvr_setup(&st, &pre##_ocb3policy, aad->b, &aad->off, p, sz); \ + RSVR_DO(&st) while ((q = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \ + OCB_OFFSET(PRE, aad->o, aad->k.lmask, aad->i++); \ + BLKC_LOAD(PRE, t, q); BLKC_XMOVE(PRE, t, aad->o); \ + pre##_eblk(&aad->k.ctx, t, t); \ + BLKC_XMOVE(PRE, aad->a, t); \ + } \ +} \ + \ +/* --- @pre_ocb3augment@ --- * \ + * \ + * Arguments: @uint32 *nn@ = where to write the augmented nonce \ + * @const octet *n@ = pointer to input nonce data \ + * @size_t nsz@ = size of input nonce \ + * @size_t tsz@ = tag length \ + * \ + * Returns: The nonce shift index. \ + * \ + * Use: Constructs the augmented base nonce, mixing in the tag \ + * length appropriately. \ + */ \ + \ +static unsigned pre##_ocb3augment(uint32 *nn, const octet *n, \ + size_t nsz, size_t tsz) \ +{ \ + octet b[PRE##_BLKSZ] = { 0 }; \ + uint32 t; \ + unsigned nix; \ + \ + b[0] = 8*(tsz%PRE##_BLKSZ) << OCB3_TSHIFT(PRE); \ + b[PRE##_BLKSZ - nsz - 1] |= 0x01; \ + memcpy(b + PRE##_BLKSZ - nsz, n, nsz); \ + BLKC_LOAD(PRE, nn, b); \ + t = BLKC_BWORD(PRE, nn[PRE##_BLKSZ/4 - 1]); \ + nix = t&OCB3_STRETCHMASK(PRE); \ + t &= ~(uint32)OCB3_STRETCHMASK(PRE); \ + nn[PRE##_BLKSZ/4 - 1] = BLKC_BWORD(PRE, t); \ + return (nix); \ +} \ + \ +/* --- @pre_ocb3stretch@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \ + * \ + * Returns: --- \ + * \ + * Use: Stretches the augmented nonce. \ + */ \ + \ +static void pre##_ocb3stretch(pre##_ocb3ctx *ctx) \ +{ \ + unsigned nw = OCB3_STRETCHSHIFT(PRE)/32, \ + nl = OCB3_STRETCHSHIFT(PRE)%32, nr = 32 - nl; \ + unsigned i; \ + uint32 c = 0, t, u; \ + \ + pre##_eblk(&ctx->k.ctx, ctx->nbase, ctx->nstretch); \ + for (i = 0; i < PRE##_BLKSZ/4; i++) \ + ctx->nstretch[i] = BLKC_BWORD(PRE, ctx->nstretch[i]); \ + i = PRE##_BLKSZ/4; \ + while (i > PRE##_BLKSZ/4 - nw) \ + { i--; ctx->nstretch[i + PRE##_BLKSZ/4] = ctx->nstretch[i]; } \ + while (i--) { \ + u = ctx->nstretch[i]; t = ctx->nstretch[i + nw]; \ + ctx->nstretch[i + PRE##_BLKSZ/4] = u ^ (t << nl) ^ c; \ + if (nr < 32) c = U32(t) >> nr; \ + } \ +} \ + \ +/* --- @pre_ocb3shift@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \ + * @unsigned nix@ = nonce index \ + * \ + * Returns: --- \ + * \ + * Use: Extracts a chunk out of the OCB3 stretched nonce and \ + * writes it to @ctx->o@. \ + */ \ + \ +static void pre##_ocb3shift(pre##_ocb3ctx *ctx, unsigned nix) \ +{ \ + unsigned nw = nix/32, nl = nix%32, nr = 32 - nl; \ + uint32 c, t; \ + unsigned i; \ + \ + i = PRE##_BLKSZ/4; \ + if (nr < 32) c = U32(ctx->nstretch[PRE##_BLKSZ/4 + nw]) >> nr; \ + else c = 0; \ + while (i--) { \ + t = ctx->nstretch[i + nw]; \ + ctx->o[i] = BLKC_BWORD(PRE, (t << nl) | c); \ + if (nr < 32) c = U32(t) >> nr; \ + } \ +} \ + \ +/* --- @pre_ocb3init@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \ + * @const pre_ocb3key *key@ = pointer to key block \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * @size_t tsz@ = tag length \ + * \ + * Returns: Zero on success, @-1@ if the nonce or tag length is \ + * bad. \ + * \ + * Use: Initialize an OCB3 operation context with a given key. \ + * \ + * The original key needn't be kept around any more. \ + */ \ + \ +int pre##_ocb3init(pre##_ocb3ctx *ctx, const pre##_ocb3key *k, \ + const void *n, size_t nsz, size_t tsz) \ +{ \ + unsigned nix; \ + \ + /* Preflight checking. */ \ + if (nsz > OCB3_NSZMAX(PRE)) return (-1); \ + if (tsz > PRE##_BLKSZ) return (-1); \ + \ + /* Copy over the blockcipher key. */ \ + ctx->k = *k; \ + \ + /* Sort out the nonce. */ \ + nix = pre##_ocb3augment(ctx->nbase, n, nsz, tsz); \ + ctx->nix = nix; ctx->tsz = tsz; \ + pre##_ocb3stretch(ctx); \ + pre##_ocb3shift(ctx, nix); \ + \ + /* Other random things. */ \ + ctx->off = 0; ctx->i = 1; \ + BLKC_ZERO(PRE, ctx->a); \ + \ + /* Done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ocb3reinit@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * @size_t tsz@ = tag length \ + * \ + * Returns: Zero on success, @-1@ if the nonce or tag length is \ + * bad. \ + * \ + * Use: Reinitialize an OCB3 operation context, changing the \ + * nonce and/or tag length. \ + */ \ + \ +int pre##_ocb3reinit(pre##_ocb3ctx *ctx, \ + const void *n, size_t nsz, size_t tsz) \ +{ \ + uint32 t[PRE##_BLKSZ/4]; \ + unsigned nix, i; \ + \ + /* Preflight checking. */ \ + if (nsz > OCB3_NSZMAX(PRE)) return (-1); \ + if (tsz > PRE##_BLKSZ) return (-1); \ + \ + /* Sort out the nonce. */ \ + nix = pre##_ocb3augment(t, n, nsz, tsz); \ + for (i = 0; i < PRE##_BLKSZ/4; i++) { \ + if (t[i] == ctx->nbase[i]) continue; \ + ctx->nix = nix; ctx->tsz = tsz; \ + BLKC_MOVE(PRE, ctx->nbase, t); pre##_ocb3stretch(ctx); \ + break; \ + } \ + pre##_ocb3shift(ctx, nix); \ + \ + /* Other random things. */ \ + ctx->off = 0; ctx->i = 1; \ + BLKC_ZERO(PRE, ctx->a); \ + \ + /* Done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ocb3step@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \ + * \ + * Returns: --- \ + * \ + * Use: Reinitialize an OCB3 operation context, stepping to \ + * the `next' nonce along. \ + */ \ + \ +void pre##_ocb3step(pre##_ocb3ctx *ctx) \ +{ \ + /* Sort out the nonce. */ \ + if (ctx->nix < OCB3_STRETCHMASK(PRE)) \ + pre##_ocb3shift(ctx, ++ctx->nix); \ + else { \ + ctx->nix = 0; \ + BLKC_BADD(PRE, ctx->nbase, OCB3_STRETCHMASK(PRE) + 1); \ + pre##_ocb3stretch(ctx); \ + pre##_ocb3shift(ctx, 0); \ + } \ + \ + /* Other random things. */ \ + ctx->off = 0; ctx->i = 1; \ + BLKC_ZERO(PRE, ctx->a); \ +} \ + \ +/* --- @pre_ocb3encrypt@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 operation context \ + * @const void *src@ = pointer to plaintext message chunk \ + * @size_t sz@ = size of the plaintext \ + * @buf *dst@ = a buffer to write the ciphertext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Encrypts a chunk of a plaintext message, writing a \ + * chunk of ciphertext to the output buffer and updating \ + * the operation state. \ + * \ + * Note that OCB3 delays output if its input is not a \ + * whole number of blocks. This means that the output \ + * might be smaller or larger the input by up to the block \ + * size. \ + */ \ + \ +int pre##_ocb3encrypt(pre##_ocb3ctx *ctx, \ + const void *src, size_t sz, buf *dst) \ +{ \ + rsvr_state st; \ + size_t osz; \ + uint32 t[PRE##_BLKSZ/4]; \ + const octet *p; \ + octet *q; \ + \ + /* Figure out what we're going to do. */ \ + rsvr_setup(&st, &pre##_ocb3policy, ctx->b, &ctx->off, src, sz); \ + \ + /* Determine the output size and verify that there is enough \ + * space. \ + */ \ + osz = st.plan.from_rsvr + st.plan.from_input; \ + if (!osz) q = 0; \ + else { q = buf_get(dst, osz); if (!q) return (-1); } \ + \ + /* Process the input in whole blocks at a time. */ \ + RSVR_DO(&st) while ((p = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \ + OCB_OFFSET(PRE, ctx->o, ctx->k.lmask, ctx->i++); \ + BLKC_LOAD(PRE, t, p); BLKC_XMOVE(PRE, ctx->a, t); \ + BLKC_XMOVE(PRE, t, ctx->o); pre##_eblk(&ctx->k.ctx, t, t); \ + BLKC_XSTORE(PRE, q, t, ctx->o); q += PRE##_BLKSZ; \ + } \ + \ + /* Done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ocb3decrypt@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 operation context \ + * @const void *src@ = pointer to ciphertext message chunk \ + * @size_t sz@ = size of the ciphertext \ + * @buf *dst@ = a buffer to write the plaintext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Decrypts a chunk of a ciphertext message, writing a \ + * chunk of plaintext to the output buffer and updating \ + * the operation state. \ + * \ + * Note that OCB3 delays output if its input is not a \ + * whole number of blocks. This means that the output \ + * might be smaller or larger the input by up to the block \ + * size. \ + */ \ + \ +int pre##_ocb3decrypt(pre##_ocb3ctx *ctx, \ + const void *src, size_t sz, buf *dst) \ +{ \ + rsvr_state st; \ + size_t osz; \ + uint32 t[PRE##_BLKSZ/4]; \ + const octet *p; \ + octet *q; \ + \ + /* Figure out what we're going to do. */ \ + rsvr_setup(&st, &pre##_ocb3policy, ctx->b, &ctx->off, src, sz); \ + \ + /* Determine the output size and verify that there is enough \ + * space. \ + */ \ + osz = st.plan.from_rsvr + st.plan.from_input; \ + if (!osz) q = 0; \ + else { q = buf_get(dst, osz); if (!q) return (-1); } \ + \ + /* Process the input in whole blocks at a time. */ \ + RSVR_DO(&st) while ((p = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \ + OCB_OFFSET(PRE, ctx->o, ctx->k.lmask, ctx->i++); \ + BLKC_LOAD(PRE, t, p); \ + BLKC_XMOVE(PRE, t, ctx->o); pre##_dblk(&ctx->k.ctx, t, t); \ + BLKC_XMOVE(PRE, t, ctx->o); BLKC_XMOVE(PRE, ctx->a, t); \ + BLKC_STORE(PRE, q, t); q += PRE##_BLKSZ; \ + } \ + \ + /* Done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ocb3tag@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to an OCB3 context \ + * @const pre_ocb3aadctx *aad@ = pointer to AAD context, \ + * or null \ + * @buf *dst@ = buffer for remaining ciphertext \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Common end-of-message handling for encryption and \ + * decryption. The caller is expected to have processed \ + * the last partial block, mixing the padded plaintext \ + * into the checksum and leaving the partial output in \ + * the context's buffer: this function will write the \ + * output to the caller's output buffer. It will compute \ + * the final full-length tag and leave it in the \ + * context's buffer. \ + */ \ + \ +static int pre##_ocb3tag(pre##_ocb3ctx *ctx, \ + const pre##_ocb3aadctx *aad, buf *dst) \ +{ \ + octet *q; \ + \ + /* Arrange space for the final output (if any). */ \ + if (!ctx->off) { q = 0; if (!BOK(dst)) return (-1); } \ + else { q = buf_get(dst, ctx->off); if (!q) return (-1); } \ + \ + /* Deal with whatever's left in the input buffer, if anything */ \ + if (ctx->off) memcpy(q, ctx->b, ctx->off); \ + \ + /* Wrap up the checksum calculation. */ \ + BLKC_XMOVE(PRE, ctx->o, ctx->k.ldollar); \ + BLKC_XMOVE(PRE, ctx->a, ctx->o); \ + pre##_eblk(&ctx->k.ctx, ctx->a, ctx->a); \ + \ + /* Finish off the AAD processing. */ \ + if (aad) { \ + if (aad->i) BLKC_XMOVE(PRE, ctx->a, aad->a); \ + if (aad->off) { \ + memcpy(ctx->b, aad->b, aad->off); \ + ctx->b[aad->off] = 0x80; \ + memset(ctx->b + aad->off + 1, 0, PRE##_BLKSZ - aad->off - 1); \ + BLKC_LOAD(PRE, ctx->o, ctx->b); \ + BLKC_XMOVE(PRE, ctx->o, aad->o); \ + BLKC_XMOVE(PRE, ctx->o, ctx->k.lstar); \ + pre##_eblk(&ctx->k.ctx, ctx->o, ctx->o); \ + BLKC_XMOVE(PRE, ctx->a, ctx->o); \ + } \ + } \ + \ + /* Write the final tag. */ \ + BLKC_STORE(PRE, ctx->b, ctx->a); \ + \ + /* Done. */ \ + return (0); \ +} \ + \ +/* --- @pre_ocb3encryptdone@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to an OCB3 context \ + * @const pre_ocb3aadctx *aad@ = pointer to AAD context, \ + * or null \ + * @buf *dst@ = buffer for remaining ciphertext \ + * @void *tag@ = where to write the tag \ + * @size_t tsz@ = length of tag to store \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Completes an OCB3 encryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. OCB3 delays output, so this will \ + * cause any remaining buffered plaintext to be encrypted \ + * and written to @dst@. Anyway, the function will fail \ + * if the output buffer is broken. \ + */ \ + \ +int pre##_ocb3encryptdone(pre##_ocb3ctx *ctx, \ + const pre##_ocb3aadctx *aad, buf *dst, \ + void *tag, size_t tsz) \ +{ \ + uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ]; \ + \ + /* Deal with any final partial block. */ \ + if (ctx->off) { \ + BLKC_XMOVE(PRE, ctx->o, ctx->k.lstar); \ + ctx->b[ctx->off] = 0x80; \ + memset(ctx->b + ctx->off + 1, 0, PRE##_BLKSZ - ctx->off - 1); \ + BLKC_LOAD(PRE, t, ctx->b); \ + BLKC_XMOVE(PRE, ctx->a, t); \ + pre##_eblk(&ctx->k.ctx, ctx->o, u); \ + BLKC_XSTORE(PRE, ctx->b, t, u); \ + } \ + \ + /* Return the tag. */ \ + assert(tsz == ctx->tsz); \ + if (pre##_ocb3tag(ctx, aad, dst)) return (-1); \ + memcpy(tag, ctx->b, tsz); \ + return (0); \ +} \ + \ +/* --- @pre_ocb3decryptdone@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to an OCB3 context \ + * @const pre_ocb3aadctx *aad@ = pointer to AAD context, \ + * or null \ + * @buf *dst@ = buffer for remaining plaintext \ + * @const void *tag@ = tag to verify \ + * @size_t tsz@ = length of tag \ + * \ + * Returns: @+1@ for complete success; @0@ if tag verification \ + * failed; @-1@ for other kinds of errors. \ + * \ + * Use: Completes an OCB3 decryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. OCB3 delays output, so this will \ + * cause any remaining buffered ciphertext to be decrypted \ + * and written to @dst@. Anyway, the function will fail \ + * if the output buffer is broken. \ + */ \ + \ +int pre##_ocb3decryptdone(pre##_ocb3ctx *ctx, \ + const pre##_ocb3aadctx *aad, buf *dst, \ + const void *tag, size_t tsz) \ +{ \ + uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ]; \ + \ + /* Deal with any final partial block. */ \ + if (ctx->off) { \ + BLKC_XMOVE(PRE, ctx->o, ctx->k.lstar); \ + BLKC_LOAD(PRE, t, ctx->b); \ + pre##_eblk(&ctx->k.ctx, ctx->o, u); \ + BLKC_XSTORE(PRE, ctx->b, t, u); \ + ctx->b[ctx->off] = 0x80; \ + memset(ctx->b + ctx->off + 1, 0, PRE##_BLKSZ - ctx->off - 1); \ + BLKC_XLOAD(PRE, ctx->a, ctx->b); \ + } \ + \ + /* Check the tag. */ \ + assert(tsz == ctx->tsz); \ + if (pre##_ocb3tag(ctx, aad, dst)) return (-1); \ + if (ct_memeq(tag, ctx->b, ctx->tsz)) return (+1); \ + else return (0); \ +} \ + \ +/* --- Generic AEAD interface --- */ \ + \ +typedef struct gactx { \ + gaead_aad a; \ + pre##_ocb3aadctx aad; \ +} gactx; \ + \ +static gaead_aad *gadup(const gaead_aad *a) \ + { gactx *aad = S_CREATE(gactx); *aad = *(gactx *)a; return (&aad->a); } \ + \ +static void gahash(gaead_aad *a, const void *h, size_t hsz) \ + { gactx *aad = (gactx *)a; pre##_ocb3aadhash(&aad->aad, h, hsz); } \ + \ +static void gadestroy(gaead_aad *a) \ + { gactx *aad = (gactx *)a; BURN(*aad); S_DESTROY(aad); } \ + \ +static const gaead_aadops gaops = \ + { &pre##_ocb3, gadup, gahash, gadestroy }; \ + \ +static gaead_aad *gaad(const pre##_ocb3key *k) \ +{ \ + gactx *aad = S_CREATE(gactx); \ + aad->a.ops = &gaops; \ + pre##_ocb3aadinit(&aad->aad, k); \ + return (&aad->a); \ +} \ + \ +typedef struct gectx { \ + gaead_enc e; \ + pre##_ocb3ctx ctx; \ +} gectx; \ + \ +static gaead_aad *geaad(gaead_enc *e) \ + { gectx *enc = (gectx *)e; return (gaad(&enc->ctx.k)); } \ + \ +static int gereinit(gaead_enc *e, const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gectx *enc = (gectx *)e; \ + return (pre##_ocb3reinit(&enc->ctx, n, nsz, tsz)); \ +} \ + \ +static int geenc(gaead_enc *e, const void *m, size_t msz, buf *b) \ +{ \ + gectx *enc = (gectx *)e; \ + return (pre##_ocb3encrypt(&enc->ctx, m, msz, b)); \ +} \ + \ +static int gedone(gaead_enc *e, const gaead_aad *a, \ + buf *b, void *t, size_t tsz) \ +{ \ + gectx *enc = (gectx *)e; gactx *aad = (gactx *)a; \ + assert(!a || a->ops == &gaops); \ + return (pre##_ocb3encryptdone(&enc->ctx, a ? &aad->aad : 0, b, t, tsz)); \ +} \ + \ +static void gedestroy(gaead_enc *e) \ + { gectx *enc = (gectx *)e; BURN(*enc); S_DESTROY(enc); } \ + \ +static const gaead_encops geops = \ + { &pre##_ocb3, geaad, gereinit, geenc, gedone, gedestroy }; \ + \ +typedef struct gdctx { \ + gaead_dec d; \ + pre##_ocb3ctx ctx; \ +} gdctx; \ + \ +static gaead_aad *gdaad(gaead_dec *d) \ + { gdctx *dec = (gdctx *)d; return (gaad(&dec->ctx.k)); } \ + \ +static int gdreinit(gaead_dec *d, const void *n, size_t nsz, \ + size_t hsz, size_t csz, size_t tsz) \ +{ \ + gdctx *dec = (gdctx *)d; \ + return (pre##_ocb3reinit(&dec->ctx, n, nsz, tsz)); \ +} \ + \ +static int gddec(gaead_dec *d, const void *c, size_t csz, buf *b) \ +{ \ + gdctx *dec = (gdctx *)d; \ + return (pre##_ocb3decrypt(&dec->ctx, c, csz, b)); \ +} \ + \ +static int gddone(gaead_dec *d, const gaead_aad *a, \ + buf *b, const void *t, size_t tsz) \ +{ \ + gdctx *dec = (gdctx *)d; gactx *aad = (gactx *)a; \ + assert(!a || a->ops == &gaops); \ + return (pre##_ocb3decryptdone(&dec->ctx, a ? &aad->aad : 0, b, t, tsz)); \ +} \ + \ +static void gddestroy(gaead_dec *d) \ + { gdctx *dec = (gdctx *)d; BURN(*dec); S_DESTROY(dec); } \ + \ +static const gaead_decops gdops = \ + { &pre##_ocb3, gdaad, gdreinit, gddec, gddone, gddestroy }; \ + \ +typedef struct gkctx { \ + gaead_key k; \ + pre##_ocb3key key; \ +} gkctx; \ + \ +static gaead_aad *gkaad(const gaead_key *k) \ + { gkctx *key = (gkctx *)k; return (gaad(&key->key)); } \ + \ +static gaead_enc *gkenc(const gaead_key *k, const void *n, size_t nsz, \ + size_t hsz, size_t msz, size_t tsz) \ +{ \ + gkctx *key = (gkctx *)k; \ + gectx *enc = S_CREATE(gectx); \ + \ + enc->e.ops = &geops; \ + if (pre##_ocb3init(&enc->ctx, &key->key, n, nsz, tsz)) \ + { gedestroy(&enc->e); return (0); } \ + return (&enc->e); \ +} \ + \ +static gaead_dec *gkdec(const gaead_key *k, const void *n, size_t nsz, \ + size_t hsz, size_t csz, size_t tsz) \ +{ \ + gkctx *key = (gkctx *)k; \ + gdctx *dec = S_CREATE(gdctx); \ + \ + dec->d.ops = &gdops; \ + if (pre##_ocb3init(&dec->ctx, &key->key, n, nsz, tsz)) \ + { gddestroy(&dec->d); return (0); } \ + return (&dec->d); \ +} \ + \ +static void gkdestroy(gaead_key *k) \ + { gkctx *key = (gkctx *)k; BURN(*key); S_DESTROY(key); } \ + \ +static const gaead_keyops gkops = \ + { &pre##_ocb3, gkaad, gkenc, gkdec, gkdestroy }; \ + \ +static gaead_key *gckey(const void *k, size_t ksz) \ +{ \ + gkctx *key = S_CREATE(gkctx); \ + key->k.ops = &gkops; \ + pre##_ocb3setkey(&key->key, k, ksz); \ + return (&key->k); \ +} \ + \ +const gcaead pre##_ocb3 = { \ + name "-ocb3", \ + pre##_keysz, pre##_ocb3noncesz, pre##_ocb3tagsz, \ + PRE##_BLKSZ, PRE##_BLKSZ - 1, 0, AEADF_PCTSZ, \ + gckey \ +}; \ + \ +OCB3_TESTX(PRE, pre, name, fname) + +/*----- Test rig ----------------------------------------------------------*/ + +#define OCB3_TEST(PRE, pre) OCB3_TESTX(PRE, pre, #pre, #pre) + +/* --- @OCB3_TEST@ --- * + * + * Arguments: @PRE, pre@ = prefixes for the underlying block cipher + * + * Use: Standard test rig for OCB3 functions. + */ + +#ifdef TEST_RIG + +#include + +#include +#include +#include + +#define OCB3_TESTX(PRE, pre, name, fname) \ + \ +static int ocb3verify(dstr *v) \ +{ \ + pre##_ocb3key key; \ + pre##_ocb3aadctx aad; \ + pre##_ocb3ctx ctx; \ + int ok = 1, win; \ + int i; \ + octet *p; \ + int szs[] = { 1, 7, 192, -1, 0 }, *ip; \ + size_t hsz, msz; \ + dstr d = DSTR_INIT, t = DSTR_INIT; \ + buf b; \ + \ + dstr_ensure(&d, v[4].len > v[3].len ? v[4].len : v[3].len); \ + dstr_ensure(&t, v[5].len); t.len = v[5].len; \ + \ + pre##_ocb3setkey(&key, v[0].buf, v[0].len); \ + \ + for (ip = szs; *ip; ip++) { \ + \ + pre##_ocb3init(&ctx, &key, (octet *)v[1].buf, v[1].len, v[5].len); \ + \ + i = *ip; \ + hsz = v[2].len; \ + if (i == -1) i = hsz; \ + if (i > hsz) continue; \ + p = (octet *)v[2].buf; \ + pre##_ocb3aadinit(&aad, &key); \ + while (hsz) { \ + if (i > hsz) i = hsz; \ + pre##_ocb3aadhash(&aad, p, i); \ + p += i; hsz -= i; \ + } \ + \ + buf_init(&b, d.buf, d.sz); \ + i = *ip; \ + msz = v[3].len; \ + if (i == -1) i = msz; \ + if (i > msz) continue; \ + p = (octet *)v[3].buf; \ + while (msz) { \ + if (i > msz) i = msz; \ + if (pre##_ocb3encrypt(&ctx, p, i, &b)) { \ + puts("!! ocb3encrypt reports failure"); \ + goto fail_enc; \ + } \ + p += i; msz -= i; \ + } \ + \ + if (pre##_ocb3encryptdone(&ctx, &aad, &b, (octet *)t.buf, t.len)) { \ + puts("!! ocb3encryptdone reports failure"); \ + goto fail_enc; \ + } \ + d.len = BLEN(&b); \ + \ + if (d.len != v[4].len || \ + memcmp(d.buf, v[4].buf, v[4].len) != 0 || \ + memcmp(t.buf, v[5].buf, v[5].len) != 0) { \ + fail_enc: \ + printf("\nfail encrypt:\n\tstep = %i", *ip); \ + fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \ + fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \ + fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \ + fputs("\n\tmessage = ", stdout); type_hex.dump(&v[3], stdout); \ + fputs("\n\texp ct = ", stdout); type_hex.dump(&v[4], stdout); \ + fputs("\n\tcalc ct = ", stdout); type_hex.dump(&d, stdout); \ + fputs("\n\texp tag = ", stdout); type_hex.dump(&v[5], stdout); \ + fputs("\n\tcalc tag = ", stdout); type_hex.dump(&t, stdout); \ + putchar('\n'); \ + ok = 0; \ + } \ + \ + pre##_ocb3init(&ctx, &key, (octet *)v[1].buf, v[1].len, v[5].len); \ + \ + buf_init(&b, d.buf, d.sz); \ + i = *ip; \ + msz = v[4].len; \ + if (i == -1) i = msz; \ + if (i > msz) continue; \ + p = (octet *)v[4].buf; \ + while (msz) { \ + if (i > msz) i = msz; \ + if (pre##_ocb3decrypt(&ctx, p, i, &b)) { \ + puts("!! ocb3decrypt reports failure"); \ + win = 0; goto fail_dec; \ + } \ + p += i; msz -= i; \ + } \ + \ + win = pre##_ocb3decryptdone(&ctx, &aad, &b, \ + (octet *)v[5].buf, v[5].len); \ + if (win < 0) { \ + puts("!! ocb3decryptdone reports failure"); \ + goto fail_dec; \ + } \ + d.len = BLEN(&b); \ + \ + if (d.len != v[3].len || !win || \ + memcmp(d.buf, v[3].buf, v[3].len) != 0) { \ + fail_dec: \ + printf("\nfail decrypt:\n\tstep = %i", *ip); \ + fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \ + fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \ + fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \ + fputs("\n\tciphertext = ", stdout); type_hex.dump(&v[4], stdout); \ + fputs("\n\texp pt = ", stdout); type_hex.dump(&v[3], stdout); \ + fputs("\n\tcalc pt = ", stdout); type_hex.dump(&d, stdout); \ + fputs("\n\ttag = ", stdout); type_hex.dump(&v[5], stdout); \ + printf("\n\tverify %s", win ? "ok" : "FAILED"); \ + putchar('\n'); \ + ok = 0; \ + } \ + } \ + \ + dstr_destroy(&d); dstr_destroy(&t); \ + return (ok); \ +} \ + \ +static int ocb3mct(dstr *v) \ +{ \ + unsigned ksz = *(unsigned long *)v[0].buf, tsz = v[1].len; \ + dstr d = DSTR_INIT; \ + octet z[128]; \ + pre##_ocb3key k; \ + pre##_ocb3ctx ctx; \ + pre##_ocb3aadctx oaad, iaad; \ + int rc; \ + buf b; \ + unsigned i; \ + int ok = 1; \ + \ + dstr_ensure(&d, ksz); memset(d.buf, 0, ksz - 4); \ + STORE32_B(d.buf + ksz - 4, 8*tsz); \ + pre##_ocb3setkey(&k, d.buf, ksz); \ + \ + pre##_ocb3aadinit(&oaad, &k); \ + \ + dstr_ensure(&d, 128 + tsz); \ + memset(z, 0, 128); \ + pre##_ocb3init(&ctx, &k, z, PRE##_BLKSZ - 4, tsz); \ + \ + for (i = 0; i < 128; i++) { \ + pre##_ocb3aadinit(&iaad, &k); pre##_ocb3aadhash(&iaad, z, i); \ + \ + pre##_ocb3step(&ctx); buf_init(&b, d.buf, i); \ + rc = pre##_ocb3encrypt(&ctx, z, i, &b); if (rc) goto fail; \ + rc = pre##_ocb3encryptdone(&ctx, &iaad, &b, d.buf + i, tsz); \ + if (rc) goto fail; \ + pre##_ocb3aadhash(&oaad, d.buf, i + tsz); \ + \ + pre##_ocb3step(&ctx); buf_init(&b, d.buf, i); \ + rc = pre##_ocb3encrypt(&ctx, z, i, &b); if (rc) goto fail; \ + rc = pre##_ocb3encryptdone(&ctx, 0, &b, d.buf + i, tsz); \ + if (rc) goto fail; \ + pre##_ocb3aadhash(&oaad, d.buf, i + tsz); \ + \ + pre##_ocb3step(&ctx); buf_init(&b, 0, 0); \ + rc = pre##_ocb3encryptdone(&ctx, &iaad, &b, d.buf, tsz); \ + if (rc) goto fail; \ + pre##_ocb3aadhash(&oaad, d.buf, tsz); \ + } \ + \ + pre##_ocb3step(&ctx); buf_init(&b, 0, 0); \ + rc = pre##_ocb3encryptdone(&ctx, &oaad, &b, d.buf, tsz); \ + if (rc) goto fail; \ + \ + d.len = tsz; \ + if (memcmp(d.buf, v[1].buf, tsz) != 0) { \ + fail: \ + printf("\nfail mct: ksz = %u, tsz = %u", ksz, tsz); \ + fputs("\n\texp tag = ", stdout); type_hex.dump(&v[1], stdout); \ + fputs("\n\tcalc tag = ", stdout); type_hex.dump(&d, stdout); \ + putchar('\n'); \ + ok = 0; \ + } \ + \ + return (ok); \ +} \ + \ +static test_chunk aeaddefs[] = { \ + { name "-ocb3", ocb3verify, \ + { &type_hex, &type_hex, &type_hex, &type_hex, \ + &type_hex, &type_hex, 0 } }, \ + { name "-ocb3-mct", ocb3mct, \ + { &type_ulong, &type_hex, 0 } }, \ + { 0, 0, { 0 } } \ +}; \ + \ +int main(int argc, char *argv[]) \ +{ \ + ego(argv[0]); \ + test_run(argc, argv, aeaddefs, SRCDIR"/t/" fname); \ + return (0); \ +} + +#else +# define OCB3_TESTX(PRE, pre, name, fname) +#endif + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/ocb3.h b/symm/ocb3.h new file mode 100644 index 00000000..ceb2df02 --- /dev/null +++ b/symm/ocb3.h @@ -0,0 +1,337 @@ +/* -*-c-*- + * + * The OCB3 authenticated encryption mode + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Notes on OCB3 -----------------------------------------------------* + * + * OCB3 was designed in 2011 by Phillip Rogaway and Ted Krovetz, building ten + * years of earlier work by Rogaway, Bellare, and Black, and refining Jutla's + * pioneering work on IACBC and IAPM. OCB3 is an efficient `authenticated + * encryption with associated data' (AEAD) scheme which requires only one + * blockcipher application per message block. + * + * The patent situation on these efficient authenticated encryption schemes + * is fraught. IBM hold two patents on Jutla's pioneering work on `IACBC' + * and `IAPM' which can apply (a third was filed at least six years too + * late), and Virgil Gligor and Pompiliu Donescu hold patents on their `XECB' + * and `XCBC' modes; these may or may not apply to OCB. Rogaway himself + * holds US patents on various versions of OCB, but has issued free licences + * for free (`open source') software, and for all non-military use. I think + * Catacomb's implementation of OCB falls within the scope of the former + * licence. + * + * OCB3 has optimized for short messages with `similar' nonces, where + * `similar' means `all but the low bits in the last byte are equal'; exactly + * how many bits depends on the block length in a rather complicated manner. + * This implementation supports this optimization through @pre_ocb3reinit@ + * (which compares the new nonce against the old one to see whether it can + * make use of the similarity), and, more directly, through @pre_ocb3step@, + * which (effectively) advances the nonce as a big-endian counter. + * + * OCB3 was originally defined only for 128-bit blockciphers, and extending + * it to other sizes is nontrivial, but this has been done by Ted Krovetz in + * I-D draft-krovetz-ocb-wideblock-00 (following initial prompting from, err, + * me). + * + * OCB3 is a fairly well-behaved AEAD mode. It doesn't require + * precommentment to the header or message lengths, but does require + * precommitment to the tag length. It permits header data to be processed + * independently of any message. It only accepts nonces the same size as the + * underlying blockcipher's block size, and it buffers up to a whole block's + * worth of data internally, which somewhat complicates streaming. + */ + +#ifndef CATACOMB_OCB3_H +#define CATACOMB_OCB3_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +#ifndef CATACOMB_GAEAD_H +# include "gaead.h" +#endif + +#ifndef CATACOMB_OCB_H +# include "ocb.h" +#endif + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @OCB3_DECL@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates declarations for OCB3 message-authentication mode. + */ + +#define OCB3_NSZMAX(PRE) (PRE##_BLKSZ - (PRE##_BLKSZ <= 16 ? 1 : 2)) + +#define OCB3_DECL(PRE, pre) \ + \ +typedef struct pre##_ocb3key { \ + pre##_ctx ctx; /* Underlying cipher context */ \ + uint32 lstar[PRE##_BLKSZ/4]; /* Partial-block mask */ \ + uint32 ldollar[PRE##_BLKSZ/4]; /* Checksum mask */ \ + uint32 lmask[OCB_NCALC][PRE##_BLKSZ/4]; /* Precalculated masks */ \ +} pre##_ocb3key; \ + \ +typedef struct pre##_ocb3aadctx { \ + pre##_ocb3key k; /* Processed key material */ \ + uint32 o[PRE##_BLKSZ/4]; /* Current offset */ \ + uint32 a[PRE##_BLKSZ/4]; /* Accumulator state */ \ + octet b[PRE##_BLKSZ]; /* Input buffer */ \ + unsigned long i; /* Block counter */ \ + unsigned off; /* Offset into buffered data */ \ +} pre##_ocb3aadctx; \ + \ +typedef struct pre##_ocb3ctx { \ + pre##_ocb3key k; /* Processed key material */ \ + unsigned nix, tsz; /* Nonce index and tag size */ \ + uint32 nbase[PRE##_BLKSZ/2]; /* Current base nonce */ \ + uint32 nstretch[PRE##_BLKSZ/2]; /* Stretched nonce material */ \ + uint32 o[PRE##_BLKSZ/4]; /* Current offset */ \ + uint32 a[PRE##_BLKSZ/4]; /* Accumulator state */ \ + octet b[PRE##_BLKSZ]; /* Input buffer */ \ + unsigned long i; /* Block counter */ \ + unsigned off; /* Offset into buffered data */ \ +} pre##_ocb3ctx; \ + \ +extern const octet pre##_ocb3noncesz[], pre##_ocb3tagsz[]; \ + \ +/* --- @pre_ocb3setkey@ --- * \ + * \ + * Arguments: @pre_ocb3key *key@ = pointer to key block to fill in \ + * @const void *k@ = pointer to key material \ + * @size_t ksz@ = size of key material \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an OCB3 key block. \ + */ \ + \ +extern void pre##_ocb3setkey(pre##_ocb3key */*key*/, \ + const void */*k*/, size_t /*ksz*/); \ + \ +/* --- @pre_ocb3aadinit@ --- * \ + * \ + * Arguments: @pre_ocb3aadctx *aad@ = pointer to AAD context \ + * @const pre_ocb3key *key@ = pointer to key block \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an OCB3 AAD (`additional authenticated \ + * data') context associated with a given key. AAD \ + * contexts can be copied and/or reused, saving time if \ + * the AAD for number of messages has a common prefix. \ + * \ + * The @key@ doesn't need to be kept around, though \ + * usually there'll at least be another copy in some OCB3 \ + * operation context because the AAD on its own isn't much \ + * good. \ + */ \ + \ +extern void pre##_ocb3aadinit(pre##_ocb3aadctx */*aad*/, \ + const pre##_ocb3key */*key*/); \ + \ +/* --- @pre_ocb3aadhash@ --- * \ + * \ + * Arguments: @pre_ocb3aadctx *aad@ = pointer to AAD context \ + * @const void *p@ = pointer to AAD material \ + * @size_t sz@ = length of AAD material \ + * \ + * Returns: --- \ + * \ + * Use: Feeds AAD into the context. \ + */ \ + \ +extern void pre##_ocb3aadhash(pre##_ocb3aadctx */*aad*/, \ + const void */*p*/, size_t /*sz*/); \ + \ +/* --- @pre_ocb3init@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \ + * @const pre_ocb3key *key@ = pointer to key block \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * @size_t tsz@ = tag length \ + * \ + * Returns: Zero on success, @-1@ if the nonce or tag length is \ + * bad. \ + * \ + * Use: Initialize an OCB3 operation context with a given key. \ + * \ + * The original key needn't be kept around any more. \ + */ \ + \ +extern int pre##_ocb3init(pre##_ocb3ctx */*ctx*/, \ + const pre##_ocb3key */*k*/, \ + const void */*n*/, size_t /*nsz*/, \ + size_t /*tsz*/); \ + \ +/* --- @pre_ocb3reinit@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \ + * @const void *n@ = pointer to nonce \ + * @size_t nsz@ = size of nonce \ + * @size_t tsz@ = tag length \ + * \ + * Returns: Zero on success, @-1@ if the nonce or tag length is \ + * bad. \ + * \ + * Use: Reinitialize an OCB3 operation context, changing the \ + * nonce and/or tag length. \ + */ \ + \ +extern int pre##_ocb3reinit(pre##_ocb3ctx */*ctx*/, \ + const void */*n*/, size_t /*nsz*/, \ + size_t /*tsz*/); \ + \ +/* --- @pre_ocb3step@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \ + * \ + * Returns: --- \ + * \ + * Use: Reinitialize an OCB3 operation context, stepping to \ + * the `next' nonce along. \ + */ \ + \ +extern void pre##_ocb3step(pre##_ocb3ctx */*ctx*/); \ + \ +/* --- @pre_ocb3encrypt@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 operation context \ + * @const void *src@ = pointer to plaintext message chunk \ + * @size_t sz@ = size of the plaintext \ + * @buf *dst@ = a buffer to write the ciphertext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Encrypts a chunk of a plaintext message, writing a \ + * chunk of ciphertext to the output buffer and updating \ + * the operation state. \ + * \ + * Note that OCB3 delays output if its input is not a \ + * whole number of blocks. This means that the output \ + * might be smaller or larger the input by up to the block \ + * size. \ + */ \ + \ +extern int pre##_ocb3encrypt(pre##_ocb3ctx */*ctx*/, \ + const void */*src*/, size_t /*sz*/, \ + buf */*dst*/); \ + \ +/* --- @pre_ocb3decrypt@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 operation context \ + * @const void *src@ = pointer to ciphertext message chunk \ + * @size_t sz@ = size of the ciphertext \ + * @buf *dst@ = a buffer to write the plaintext to \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Decrypts a chunk of a ciphertext message, writing a \ + * chunk of plaintext to the output buffer and updating \ + * the operation state. \ + * \ + * Note that OCB3 delays output if its input is not a \ + * whole number of blocks. This means that the output \ + * might be smaller or larger the input by up to the block \ + * size. \ + */ \ + \ +extern int pre##_ocb3decrypt(pre##_ocb3ctx */*ctx*/, \ + const void */*src*/, size_t /*sz*/, \ + buf */*dst*/); \ + \ +/* --- @pre_ocb3encryptdone@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to an OCB3 context \ + * @const pre_ocb3aadctx *aad@ = pointer to AAD context, \ + * or null \ + * @buf *dst@ = buffer for remaining ciphertext \ + * @void *tag@ = where to write the tag \ + * @size_t tsz@ = length of tag to store \ + * \ + * Returns: Zero on success; @-1@ on failure. \ + * \ + * Use: Completes an OCB3 encryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. OCB3 delays output, so this will \ + * cause any remaining buffered plaintext to be encrypted \ + * and written to @dst@. Anyway, the function will fail \ + * if the output buffer is broken. \ + */ \ + \ +extern int pre##_ocb3encryptdone(pre##_ocb3ctx */*ctx*/, \ + const pre##_ocb3aadctx */*aad*/, \ + buf */*dst*/, \ + void */*tag*/, size_t /*tsz*/); \ + \ +/* --- @pre_ocb3decryptdone@ --- * \ + * \ + * Arguments: @pre_ocb3ctx *ctx@ = pointer to an OCB3 context \ + * @const pre_ocb3aadctx *aad@ = pointer to AAD context, \ + * or null \ + * @buf *dst@ = buffer for remaining plaintext \ + * @const void *tag@ = tag to verify \ + * @size_t tsz@ = length of tag \ + * \ + * Returns: @+1@ for complete success; @0@ if tag verification \ + * failed; @-1@ for other kinds of errors. \ + * \ + * Use: Completes an OCB3 decryption operation. The @aad@ \ + * pointer may be null if there is no additional \ + * authenticated data. OCB3 delays output, so this will \ + * cause any remaining buffered ciphertext to be decrypted \ + * and written to @dst@. Anyway, the function will fail \ + * if the output buffer is broken. \ + */ \ + \ +extern int pre##_ocb3decryptdone(pre##_ocb3ctx */*ctx*/, \ + const pre##_ocb3aadctx */*aad*/, \ + buf */*dst*/, \ + const void */*tag*/, size_t /*tsz*/); \ + \ +/* --- Generic AEAD interface --- */ \ + \ +extern const gcaead pre##_ocb3; + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/ofb-def.h b/symm/ofb-def.h index e9eb5034..e065f08a 100644 --- a/symm/ofb-def.h +++ b/symm/ofb-def.h @@ -56,6 +56,10 @@ # include "paranoia.h" #endif +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + /*----- Macros ------------------------------------------------------------*/ /* --- @OFB_DEF@ --- * @@ -87,8 +91,9 @@ void pre##_ofbgetiv(const pre##_ofbctx *ctx, void *iv) \ octet *p = iv; \ unsigned off = ctx->off; \ unsigned rest = PRE##_BLKSZ - off; \ - memcpy(p, ctx->iv + off, rest); \ - memcpy(p + rest, ctx->iv, off); \ + \ + memcpy(p, ctx->b + off, rest); \ + memcpy(p + rest, ctx->b, off); \ } \ \ /* --- @pre_ofbsetiv@ --- * \ @@ -102,10 +107,7 @@ void pre##_ofbgetiv(const pre##_ofbctx *ctx, void *iv) \ */ \ \ void pre##_ofbsetiv(pre##_ofbctx *ctx, const void *iv) \ -{ \ - memcpy(ctx->iv, iv, PRE##_BLKSZ); \ - ctx->off = PRE##_BLKSZ; \ -} \ + { memcpy(ctx->b, iv, PRE##_BLKSZ); ctx->off = 0; } \ \ /* --- @pre_ofbbdry@ --- * \ * \ @@ -119,12 +121,13 @@ void pre##_ofbsetiv(pre##_ofbctx *ctx, const void *iv) \ \ void pre##_ofbbdry(pre##_ofbctx *ctx) \ { \ - uint32 niv[PRE##_BLKSZ / 4]; \ - BLKC_LOAD(PRE, niv, ctx->iv); \ - pre##_eblk(&ctx->ctx, niv, niv); \ - BLKC_STORE(PRE, ctx->iv, niv); \ - ctx->off = PRE##_BLKSZ; \ - BURN(niv); \ + uint32 t[PRE##_BLKSZ/4]; \ + \ + BLKC_LOAD(PRE, t, ctx->b); \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + ctx->off = 0; \ + BURN(t); \ } \ \ /* --- @pre_ofbsetkey@ --- * \ @@ -138,9 +141,7 @@ void pre##_ofbbdry(pre##_ofbctx *ctx) \ */ \ \ void pre##_ofbsetkey(pre##_ofbctx *ctx, const pre##_ctx *k) \ -{ \ - ctx->ctx = *k; \ -} \ + { ctx->ctx = *k; } \ \ /* --- @pre_ofbinit@ --- * \ * \ @@ -163,6 +164,7 @@ void pre##_ofbinit(pre##_ofbctx *ctx, \ const void *iv) \ { \ static const octet zero[PRE##_BLKSZ] = { 0 }; \ + \ pre##_init(&ctx->ctx, key, sz); \ pre##_ofbsetiv(ctx, iv ? iv : zero); \ } \ @@ -183,81 +185,67 @@ void pre##_ofbinit(pre##_ofbctx *ctx, \ * cipher as a random data generator. \ */ \ \ +static const rsvr_policy pre##_ofbpolicy = { 0, PRE##_BLKSZ, PRE##_BLKSZ }; \ + \ void pre##_ofbencrypt(pre##_ofbctx *ctx, \ - const void *src, void *dest, \ - size_t sz) \ + const void *src, void *dest, \ + size_t sz) \ { \ - const octet *s = src; \ + rsvr_plan plan; \ + const octet *s = src, *p; \ octet *d = dest; \ - unsigned off = ctx->off; \ - \ - /* --- Empty blocks are trivial --- */ \ - \ - if (!sz) \ - return; \ - \ - /* --- If I can deal with the block from my buffer, do that --- */ \ - \ - if (sz < PRE##_BLKSZ - off) \ - goto small; \ - \ - /* --- Finish off what's left in my buffer --- */ \ - \ - if (!d) \ - sz -= PRE##_BLKSZ - off; \ - else { \ - while (off < PRE##_BLKSZ) { \ - register octet x = s ? *s++ : 0; \ - *d++ = ctx->iv[off++] ^ x; \ - sz--; \ + uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ/4]; \ + \ + /* Construct a plan and prepare to follow through. */ \ + rsvr_mkplan(&plan, &pre##_ofbpolicy, ctx->off, sz); \ + BLKC_LOAD(PRE, t, ctx->b); \ + \ + /* Initial portion, fulfilled from the buffer. If the chunk is small \ + * enough, then this will be the only portion. If the buffer is \ + * currently empty, then we must prepare it. \ + */ \ + if (plan.head) { \ + if (!ctx->off) { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, ctx->b, t); \ } \ + p = ctx->b + ctx->off; ctx->off += plan.head; \ + if (!d) /* nothing to do */; \ + else if (!s) { memcpy(d, p, plan.head); d += plan.head; } \ + else while (plan.head--) *d++ = *s++ ^ *p++; \ } \ \ - /* --- Main encryption loop --- */ \ - \ - { \ - uint32 iv[PRE##_BLKSZ / 4]; \ - BLKC_LOAD(PRE, iv, ctx->iv); \ - \ - for (;;) { \ - pre##_eblk(&ctx->ctx, iv, iv); \ - if (sz < PRE##_BLKSZ) \ - break; \ - if (d) { \ - if (!s) \ - BLKC_STORE(PRE, d, iv); \ - else { \ - uint32 x[PRE##_BLKSZ / 4]; \ - BLKC_LOAD(PRE, x, s); \ - BLKC_XSTORE(PRE, d, iv, x); \ - s += PRE##_BLKSZ; \ - } \ - d += PRE##_BLKSZ; \ - } \ - sz -= PRE##_BLKSZ; \ - } \ - \ - BLKC_STORE(PRE, ctx->iv, iv); \ - off = 0; \ + /* If the buffer is all used, then reset it ready for next time. */ \ + ctx->off -= plan.from_rsvr; \ + \ + /* Handle multiple whole blocks. */ \ + if (!d) while (plan.from_input) { \ + pre##_eblk(&ctx->ctx, t, t); \ + plan.from_input -= PRE##_BLKSZ; \ + } else if (!s) while (plan.from_input) { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, d, t); d += PRE##_BLKSZ; \ + plan.from_input -= PRE##_BLKSZ; \ + } else while (plan.from_input) { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_LOAD(PRE, u, s); s += PRE##_BLKSZ; \ + BLKC_XSTORE(PRE, d, t, u); d += PRE##_BLKSZ; \ + plan.from_input -= PRE##_BLKSZ; \ } \ \ - /* --- Tidying up the tail end --- */ \ - \ - if (sz) { \ - small: \ - if (!d) \ - off += sz; \ - else do { \ - register octet x = s ? *s++ : 0; \ - *d++ = ctx->iv[off++] ^ x; \ - sz--; \ - } while (sz); \ + /* Final portion. Note that the buffer must be empty if there is a \ + * tail, since otherwise the input data would have been part of the \ + * head portion instad. */ \ + if (!plan.tail) \ + BLKC_STORE(PRE, ctx->b, t); \ + else { \ + pre##_eblk(&ctx->ctx, t, t); \ + BLKC_STORE(PRE, ctx->b, t); \ + p = ctx->b; ctx->off += plan.tail; \ + if (!d) /* nothing to do */; \ + else if (!s) { memcpy(d, p, plan.tail); d += plan.tail; } \ + else while (plan.tail--) *d++ = *s++ ^ *p++; \ } \ - \ - /* --- Done --- */ \ - \ - ctx->off = off; \ - return; \ } \ \ /* --- Generic cipher interface --- */ \ @@ -278,23 +266,13 @@ static gcipher *ginit(const void *k, size_t sz) \ } \ \ static void gencrypt(gcipher *c, const void *s, void *t, size_t sz) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_ofbencrypt(&g->k, s, t, sz); \ -} \ + { gctx *g = (gctx *)c; pre##_ofbencrypt(&g->k, s, t, sz); } \ \ static void gdestroy(gcipher *c) \ -{ \ - gctx *g = (gctx *)c; \ - BURN(*g); \ - S_DESTROY(g); \ -} \ + { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); } \ \ static void gsetiv(gcipher *c, const void *iv) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_ofbsetiv(&g->k, iv); \ -} \ + { gctx *g = (gctx *)c; pre##_ofbsetiv(&g->k, iv); } \ \ static void gbdry(gcipher *c) \ { \ @@ -320,11 +298,7 @@ typedef struct grctx { \ } grctx; \ \ static void grdestroy(grand *r) \ -{ \ - grctx *g = (grctx *)r; \ - BURN(*g); \ - S_DESTROY(g); \ -} \ + { grctx *g = (grctx *)r; BURN(*g); S_DESTROY(g); } \ \ static int grmisc(grand *r, unsigned op, ...) \ { \ @@ -403,10 +377,7 @@ static uint32 grword(grand *r) \ } \ \ static void grfill(grand *r, void *p, size_t sz) \ -{ \ - grctx *g = (grctx *)r; \ - pre##_ofbencrypt(&g->k, 0, p, sz); \ -} \ + { grctx *g = (grctx *)r; pre##_ofbencrypt(&g->k, 0, p, sz); } \ \ static const grand_ops grops = { \ name "-ofb", \ @@ -442,9 +413,7 @@ OFB_TESTX(PRE, pre, name, name) #ifdef TEST_RIG -#include - -#include "daftstory.h" +#include "modes-test.h" /* --- @OFB_TEST@ --- * * @@ -453,87 +422,26 @@ OFB_TESTX(PRE, pre, name, name) * Use: Standard test rig for OFB functions. */ -#define OFB_TESTX(PRE, pre, name, fname) \ - \ -/* --- Initial plaintext for the test --- */ \ - \ -static const octet text[] = TEXT; \ - \ -/* --- Key and IV to use --- */ \ +#define OFB_TESTX(PRE, pre, name, fname) \ \ -static const octet key[] = KEY; \ -static const octet iv[] = IV; \ +static pre##_ctx key; \ +static pre##_ofbctx ctx; \ \ -/* --- Buffers for encryption and decryption output --- */ \ +static void pre##_ofb_test_setup(const octet *k, size_t ksz) \ + { pre##_init(&key, k, ksz); pre##_ofbsetkey(&ctx, &key); } \ \ -static octet ct[sizeof(text)]; \ -static octet pt[sizeof(text)]; \ +static void pre##_ofb_test_reset(const octet *iv) \ + { pre##_ofbsetiv(&ctx, iv); } \ \ -static void hexdump(const octet *p, size_t sz, size_t off) \ -{ \ - const octet *q = p + sz; \ - for (sz = 0; p < q; p++, sz++) { \ - printf("%02x", *p); \ - if ((off + sz + 1) % PRE##_BLKSZ == 0) \ - putchar(':'); \ - } \ -} \ +static void pre##_ofb_test_enc(const octet *s, octet *d, size_t sz) \ + { pre##_ofbencrypt(&ctx, s, d, sz); } \ \ -int main(void) \ +int main(int argc, char *argv[]) \ { \ - size_t sz = 0, rest; \ - pre##_ofbctx ctx; \ - int status = 0; \ - int done = 0; \ - pre##_ctx k; \ - \ - size_t keysz = PRE##_KEYSZ ? \ - PRE##_KEYSZ : strlen((const char *)key); \ - \ - fputs(name "-ofb: ", stdout); \ - \ - pre##_init(&k, key, keysz); \ - pre##_ofbsetkey(&ctx, &k); \ - \ - while (sz <= sizeof(text)) { \ - rest = sizeof(text) - sz; \ - memcpy(ct, text, sizeof(text)); \ - pre##_ofbsetiv(&ctx, iv); \ - pre##_ofbencrypt(&ctx, ct, ct, sz); \ - pre##_ofbencrypt(&ctx, ct + sz, ct + sz, rest); \ - memcpy(pt, ct, sizeof(text)); \ - pre##_ofbsetiv(&ctx, iv); \ - pre##_ofbencrypt(&ctx, pt, pt, rest); \ - pre##_ofbencrypt(&ctx, pt + rest, pt + rest, sz); \ - if (memcmp(pt, text, sizeof(text)) == 0) { \ - done++; \ - if (sizeof(text) < 40 || done % 8 == 0) \ - fputc('.', stdout); \ - if (done % 480 == 0) \ - fputs("\n\t", stdout); \ - fflush(stdout); \ - } else { \ - printf("\nError (sz = %lu)\n", (unsigned long)sz); \ - status = 1; \ - printf("\tplaintext = "); hexdump(text, sz, 0); \ - printf(", "); hexdump(text + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\tciphertext = "); hexdump(ct, sz, 0); \ - printf(", "); hexdump(ct + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\trecovered text = "); hexdump(pt, sz, 0); \ - printf(", "); hexdump(pt + sz, rest, sz); \ - fputc('\n', stdout); \ - fputc('\n', stdout); \ - } \ - if (sz < 63) \ - sz++; \ - else \ - sz += 9; \ - } \ - \ - fputs(status ? " failed\n" : " ok\n", stdout); \ - return (status); \ + return test_encmode(fname "-ofb", PRE##_KEYSZ, PRE##_BLKSZ, 1, 0, \ + pre##_ofb_test_setup, pre##_ofb_test_reset, \ + pre##_ofb_test_enc, pre##_ofb_test_enc, \ + argc, argv); \ } #else diff --git a/symm/ofb.h b/symm/ofb.h index 5eec2ff0..6603a4de 100644 --- a/symm/ofb.h +++ b/symm/ofb.h @@ -62,7 +62,7 @@ typedef struct pre##_ofbctx { \ pre##_ctx ctx; /* Underlying cipher context */ \ unsigned off; /* Current offset in buffer */ \ - octet iv[PRE##_BLKSZ]; /* Output buffer and IV */ \ + octet b[PRE##_BLKSZ]; /* Output buffer and IV */ \ } pre##_ofbctx; \ \ /* --- @pre_ofbgetiv@ --- * \ diff --git a/symm/pmac1-def.h b/symm/pmac1-def.h new file mode 100644 index 00000000..4b0da048 --- /dev/null +++ b/symm/pmac1-def.h @@ -0,0 +1,371 @@ +/* -*-c-*- + * + * The PMAC1 message authentication mode + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef CATACOMB_PMAC1_DEF_H +#define CATACOMB_PMAC1_DEF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include +#include + +#ifndef CATACOMB_ARENA_H +# include "arena.h" +#endif + +#ifndef CATACOMB_BLKC_H +# include "blkc.h" +#endif + +#ifndef CATACOMB_PARANOIA_H +# include "paranoia.h" +#endif + +#ifndef CATACOMB_RSVR_H +# include "rsvr.h" +#endif + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @PMAC1_DEF@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates an implementation for the PMAC1 message- + * authentication mode. + */ + +#define PMAC1_DEF(PRE, pre) PMAC1_DEFX(PRE, pre, #pre, #pre) + +#define PMAC1_DEFX(PRE, pre, name, fname) \ + \ +OCB1_DECL(PRE, pre) \ + \ +const rsvr_policy pre##_ocb1policy = \ + { RSVRF_FULL, PRE##_BLKSZ, PRE##_BLKSZ }; \ + \ +/* --- @pre_ocb1setkey@, @pre_pmac1setkey@ --- * \ + * \ + * Arguments: @pre_ocb1key *key@ = pointer to OCB1/PMAC1 key block \ + * @ocnst void *k@ = pointer to key material \ + * @size_t ksz@ = size of key material \ + * \ + * Returns: --- \ + * \ + * Use: Initializes a OCB1/PMAC1 key. This can be used for \ + * several encryption and/or MAC operations. \ + */ \ + \ +void pre##_ocb1setkey(pre##_ocb1key *key, const void *k, size_t ksz) \ +{ \ + unsigned i; \ + \ + pre##_init(&key->ctx, k, ksz); \ + BLKC_ZERO(PRE, key->lmask[0]); \ + pre##_eblk(&key->ctx, key->lmask[0], key->lmask[0]); \ + BLKC_BRSHIFT(PRE, IRRED, key->lxinv, key->lmask[0]); \ + for (i = 1; i < OCB_NCALC; i++) \ + BLKC_BLSHIFT(PRE, IRRED, key->lmask[i], key->lmask[i - 1]); \ +} \ +void pre##_pmac1setkey(pre##_pmac1key *key, const void *k, size_t ksz) \ + { pre##_ocb1setkey((pre##_ocb1key *)key, k, ksz); } \ + \ +/* --- @pre_ocb1aadinit@, @pre_pmac1init --- * \ + * \ + * Arguments: @pre_ocb1aadctx *aad@ = pointer to context block \ + * @pre_ocb1key *k@ = key block \ + * \ + * Returns: --- \ + * \ + * Use: Initializes an OCB1 AAD (`additional authenticated \ + * data') or PMAC1 context associated witha a given key. \ + * AAD contexts can be copied and/or reused, saving time \ + * if the AAD for a number of messages has a common \ + * prefix. \ + * \ + * The @key@ doesn't need to be kept around. \ + */ \ + \ +void pre##_ocb1aadinit(pre##_ocb1aadctx *aad, const pre##_ocb1key *k) \ +{ \ + aad->k = *k; \ + aad->off = 0; aad->i = 1; \ + BLKC_ZERO(PRE, aad->a); \ + BLKC_ZERO(PRE, aad->o); \ +} \ +void pre##_pmac1init(pre##_pmac1ctx *ctx, const pre##_pmac1key *k) \ + { pre##_ocb1aadinit((pre##_ocb1aadctx *)ctx, (pre##_ocb1key *)k); } \ + \ +/* --- @pre_ocb1aadhash@, @pre_pmac1hash@ --- * \ + * \ + * Arguments: @pre_ocb1aadctx *aad@ = pointer to context block \ + * @ocnst void *p@ = pointer to message buffer \ + * @size_t sz@ = size of message buffer \ + * \ + * Returns: --- \ + * \ + * Use: Hashes some AAD input data. \ + */ \ + \ +void pre##_ocb1aadhash(pre##_ocb1aadctx *aad, const void *p, size_t sz) \ +{ \ + rsvr_state st; \ + uint32 t[PRE##_BLKSZ/4]; \ + const octet *q; \ + \ + rsvr_setup(&st, &pre##_ocb1policy, aad->b, &aad->off, p, sz); \ + RSVR_DO(&st) while ((q = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \ + OCB_OFFSET(PRE, aad->o, aad->k.lmask, aad->i++); \ + BLKC_LOAD(PRE, t, q); BLKC_XMOVE(PRE, t, aad->o); \ + pre##_eblk(&aad->k.ctx, t, t); \ + BLKC_XMOVE(PRE, aad->a, t); \ + } \ +} \ +void pre##_pmac1hash(pre##_pmac1ctx *ctx, const void *p, size_t sz) \ + { pre##_ocb1aadhash((pre##_ocb1aadctx *)ctx, p, sz); } \ + \ +/* --- @pre_ocb1aadtag@ --- * \ + * \ + * Arguments: @const pre_ocb1aadctx *aad@ = pointer to context block \ + * @uint32 *u@ = where to write the tag \ + * \ + * Returns: --- \ + * \ + * Use: Finishes processing AAD and produces a tag which can be \ + * mixed with an OCB1 checksum. This function is exposed \ + * for internal reasons and is not expected to be \ + * generally useful. \ + */ \ + \ +void pre##_ocb1aadtag(const pre##_ocb1aadctx *aad, uint32 *t) \ +{ \ + octet b[PRE##_BLKSZ]; \ + \ + BLKC_MOVE(PRE, t, aad->a); \ + if (aad->off == PRE##_BLKSZ) { \ + BLKC_XLOAD(PRE, t, aad->b); \ + BLKC_XMOVE(PRE, t, aad->k.lxinv); \ + } else { \ + memcpy(b, aad->b, aad->off); b[aad->off] = 0x80; \ + memset(b + aad->off + 1, 0, PRE##_BLKSZ - aad->off - 1); \ + BLKC_XLOAD(PRE, t, b); \ + } \ + pre##_eblk(&aad->k.ctx, t, t); \ +} \ + \ +/* --- @pre_pmac1done@ --- * \ + * \ + * Arguments: @pre_pmac1ctx *ctx@ = pointer to context block \ + * @void *t@ = where to write the tag \ + * \ + * Returns: --- \ + * \ + * Use: Finishes a MAC operation and produces the tag. The \ + * context is clobbered and can't be used for anything \ + * useful any more. \ + */ \ + \ +void pre##_pmac1done(pre##_pmac1ctx *ctx, void *t) \ +{ \ + uint32 u[PRE##_BLKSZ]; \ + pre##_ocb1aadtag((pre##_ocb1aadctx *)ctx, u); BLKC_STORE(PRE, t, u); \ +} \ + \ +/* --- Generic MAC interface --- */ \ + \ +static const gmac_ops gkops; \ +static const ghash_ops gops; \ + \ +typedef struct gkctx { \ + gmac m; \ + pre##_pmac1key k; \ +} gkctx; \ + \ +typedef struct gctx { \ + ghash h; \ + pre##_pmac1ctx c; \ + octet buf[PRE##_BLKSZ]; \ +} gctx; \ + \ +static ghash *gkinit(gmac *m) \ +{ \ + gkctx *gk = (gkctx *)m; \ + gctx *g = S_CREATE(gctx); \ + g->h.ops = &gops; \ + pre##_pmac1init(&g->c, &gk->k); \ + return (&g->h); \ +} \ + \ +static gmac *gkey(const void *k, size_t sz) \ +{ \ + gkctx *gk = S_CREATE(gkctx); \ + gk->m.ops = &gkops; \ + pre##_pmac1setkey(&gk->k, k, sz); \ + return (&gk->m); \ +} \ + \ +static void ghhash(ghash *h, const void *p, size_t sz) \ + { gctx *g = (gctx *)h; pre##_pmac1hash(&g->c, p, sz); } \ + \ +static octet *ghdone(ghash *h, void *buf) \ +{ \ + gctx *g = (gctx *)h; \ + if (!buf) buf = g->buf; \ + pre##_pmac1done(&g->c, buf); \ + return (buf); \ +} \ + \ +static ghash *ghcopy(ghash *h) \ +{ \ + gctx *g = (gctx *)h; \ + gctx *gg = S_CREATE(gctx); \ + memcpy(gg, g, sizeof(gctx)); \ + return (&gg->h); \ +} \ + \ +static void ghdestroy(ghash *h) \ + { gctx *g = (gctx *)h; BURN(*g); S_DESTROY(g); } \ + \ +static void gkdestroy(gmac *m) \ + { gkctx *gk = (gkctx *)m; BURN(*gk); S_DESTROY(gk); } \ + \ +static ghash *ghinit(void) \ +{ \ + assert(((void)"Attempt to instantiate an unkeyed MAC", 0)); \ + return (0); \ +} \ + \ +const gcmac pre##_pmac1 = \ + { name "-pmac1", PRE##_BLKSZ, pre##_keysz, gkey }; \ +static const gmac_ops gkops = { &pre##_pmac1, gkinit, gkdestroy }; \ +static const gchash gch = { name "-pmac1", PRE##_BLKSZ, ghinit }; \ +static const ghash_ops gops = \ + { &gch, ghhash, ghdone, ghdestroy, ghcopy }; \ + \ +PMAC1_TESTX(PRE, pre, name, fname) + +#define PMAC1_TEST(PRE, pre) HMAC_TESTX(PRE, pre, #pre, #pre) + +/* --- @PMAC1_TEST@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Standard test rig for PMAC1 functions. + */ + +#ifdef TEST_RIG + +#include + +#include +#include +#include + +#define PMAC1_TESTX(PRE, pre, name, fname) \ + \ +static int macverify(dstr *v) \ +{ \ + pre##_pmac1ctx cctx; \ + pre##_pmac1key ckey; \ + int ok = 1; \ + int i; \ + octet *p; \ + int szs[] = { 1, 7, 192, -1, 0 }, *ip; \ + size_t csz; \ + dstr d; \ + \ + dstr_create(&d); \ + dstr_ensure(&d, PRE##_BLKSZ); \ + d.len = PRE##_BLKSZ; \ + \ + pre##_pmac1setkey(&ckey, v[0].buf, v[0].len); \ + \ + for (ip = szs; *ip; ip++) { \ + i = *ip; \ + csz = v[1].len; \ + if (i == -1) \ + i = csz; \ + if (i > csz) \ + continue; \ + p = (octet *)v[1].buf; \ + pre##_pmac1init(&cctx, &ckey); \ + while (csz) { \ + if (i > csz) \ + i = csz; \ + pre##_pmac1hash(&cctx, p, i); \ + p += i; \ + csz -= i; \ + } \ + pre##_pmac1done(&cctx, d.buf); \ + if (memcmp(d.buf, v[2].buf, PRE##_BLKSZ) != 0) { \ + printf("\nfail:\n\tstep = %i\n\tkey = ", *ip); \ + type_hex.dump(&v[0], stdout); \ + fputs("\n\tinput = ", stdout); \ + type_hex.dump(&v[1], stdout); \ + fputs("\n\texpected = ", stdout); \ + type_hex.dump(&v[2], stdout); \ + fputs("\n\tcomputed = ", stdout); \ + type_hex.dump(&d, stdout); \ + putchar('\n'); \ + ok = 0; \ + } \ + } \ + \ + dstr_destroy(&d); \ + return (ok); \ +} \ + \ +static test_chunk macdefs[] = { \ + { name "-pmac1", macverify, \ + { &type_hex, &type_hex, &type_hex, 0 } }, \ + { 0, 0, { 0 } } \ +}; \ + \ +int main(int argc, char *argv[]) \ +{ \ + ego(argv[0]); \ + test_run(argc, argv, macdefs, SRCDIR"/t/" fname); \ + return (0); \ +} + +#else +# define PMAC1_TESTX(PRE, pre, name, fname) +#endif + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/pmac1.h b/symm/pmac1.h new file mode 100644 index 00000000..88827bbe --- /dev/null +++ b/symm/pmac1.h @@ -0,0 +1,119 @@ +/* -*-c-*- + * + * The PMAC1 message authentication mode + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Notes on PMAC1 ----------------------------------------------------* + * + * PMAC was designed in 2002 by John Black and Phillip Rogaway as a + * blockcipher-based MAC which can operate on multiple message blocks in + * parallel. Unfortunately, Rogaway applied for patents on PMAC, and as a + * result it saw limited adoption. Rogaway has since abandoned the patent + * applications, and PMAC is free for all uses. + * + * Confusingly, Rogaway's 2004 paper `Efficient Instantiations of Tweakable + * Blockciphers and Refinements to Modes OCB and PMAC' named the new versions + * of those modes `OCB1' and `PMAC1'. The 2011 paper by Krovetz and Rogaway, + * `The Software Performance of Authenticated-Encryption Modes' renamed the + * original 2001 version of OCB as `OCB1', and the 2004 version `OCB2', and + * introduced a new `OCB3', but does not mention PMAC. (PMAC is used as-is + * in the 2001 and 2004 versions of OCB, to process header data; the header + * processing in the 2011 version of OCB is not a secure standalone MAC, so + * there is no PMAC3.) I've decided to follow and extend the 2011 naming, so + * `PMAC1' refers to the 2002 PMAC; the 2004 version would be `PMAC2'. + * + * This implementation does not currently attempt to process blocks in + * parallel, though this is a possible future improvement. + */ + +#ifndef CATACOMB_PMAC1_H +#define CATACOMB_PMAC1_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include + +#ifndef CATACOMB_GMAC_H +# include "gmac.h" +#endif + +#ifndef CATACOMB_OCB1_H +# include "ocb1.h" +#endif + +/*----- Macros ------------------------------------------------------------*/ + +/* --- @PMAC1_DECL@ --- * + * + * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher + * + * Use: Creates declarations for PMAC1 message-authentication mode. + * + * Most of these are aliases for OCB1 operations: see + * for their documentation. + */ + +#define PMAC1_DECL(PRE, pre) \ + \ +OCB1_STRUCTS(PRE, pre, pre##_pmac1key, pre##_pmac1ctx) \ + \ +extern void pre##_pmac1setkey(pre##_pmac1key */*key*/, \ + const void */*k*/, size_t /*ksz*/); \ + \ +extern void pre##_pmac1init(pre##_pmac1ctx */*ctx*/, \ + const pre##_pmac1key */*k*/); \ + \ +extern void pre##_pmac1hash(pre##_pmac1ctx */*ctx*/, \ + const void */*p*/, size_t /*sz*/); \ + \ +/* --- @pre_pmac1done@ --- * \ + * \ + * Arguments: @pre_pmac1ctx *ctx@ = pointer to PMAC1 context block \ + * @void *t@ = where to write the tag \ + * \ + * Returns: --- \ + * \ + * Use: Finishes a MAC operation and produces the tag. \ + */ \ + \ +extern void pre##_pmac1done(pre##_pmac1ctx */*ctx*/, void */*t*/); \ + \ +/* --- Generic MAC interface --- */ \ + \ +extern const gcmac pre##_pmac1; + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/symm/poly1305.c b/symm/poly1305.c index d237d4e7..c4a88a84 100644 --- a/symm/poly1305.c +++ b/symm/poly1305.c @@ -33,6 +33,7 @@ #include #include "poly1305.h" +#include "rsvr.h" /*----- Global variables --------------------------------------------------*/ @@ -536,28 +537,15 @@ static void update_full(poly1305_ctx *ctx, const octet *p) ctx->count++; } +static const rsvr_policy pol = { 0, 16, 16 }; + void poly1305_hash(poly1305_ctx *ctx, const void *p, size_t sz) { - const octet *pp = p; - size_t n; - - if (ctx->nbuf) { - if (sz < 16 - ctx->nbuf) { - memcpy(ctx->buf + ctx->nbuf, p, sz); - ctx->nbuf += sz; - return; - } - n = 16 - ctx->nbuf; - memcpy(ctx->buf + ctx->nbuf, pp, n); - update_full(ctx, ctx->buf); - pp += n; sz -= n; - } - while (sz >= 16) { - update_full(ctx, pp); - pp += 16; sz -= 16; - } - if (sz) memcpy(ctx->buf, pp, sz); - ctx->nbuf = sz; + rsvr_state st; + const octet *q = p; + + rsvr_setup(&st, &pol, &ctx->buf, &ctx->nbuf, p, sz); + RSVR_DO(&st) while ((q = RSVR_NEXT(&st, 16)) != 0) update_full(ctx, q); } /* --- @poly1305_flush@ --- * diff --git a/symm/rijndael-arm-crypto.S b/symm/rijndael-arm-crypto.S index 8a5484c8..1df81d97 100644 --- a/symm/rijndael-arm-crypto.S +++ b/symm/rijndael-arm-crypto.S @@ -25,20 +25,22 @@ /// MA 02111-1307, USA. ///-------------------------------------------------------------------------- -/// External definitions. +/// Preliminaries. #include "config.h" #include "asm-common.h" + .arch armv8-a + .fpu crypto-neon-fp-armv8 + .extern F(abort) .extern F(rijndael_rcon) + .text + ///-------------------------------------------------------------------------- /// Main code. - .arch armv8-a - .fpu crypto-neon-fp-armv8 - /// The ARM crypto extension implements a little-endian version of AES /// (though the manual doesn't actually spell this out and you have to /// experiment), but Catacomb's internal interface presents as big-endian so diff --git a/symm/rijndael-arm64-crypto.S b/symm/rijndael-arm64-crypto.S index 9f68ae84..98f61734 100644 --- a/symm/rijndael-arm64-crypto.S +++ b/symm/rijndael-arm64-crypto.S @@ -25,19 +25,21 @@ /// MA 02111-1307, USA. ///-------------------------------------------------------------------------- -/// External definitions. +/// Preliminaries. #include "config.h" #include "asm-common.h" + .arch armv8-a+crypto + .extern F(abort) .extern F(rijndael_rcon) + .text + ///-------------------------------------------------------------------------- /// Main code. - .arch armv8-a+crypto - /// The ARM crypto extension implements a little-endian version of AES /// (though the manual doesn't actually spell this out and you have to /// experiment), but Catacomb's internal interface presents as big-endian so diff --git a/symm/rijndael-base.c b/symm/rijndael-base.c index 83a49e92..2f651918 100644 --- a/symm/rijndael-base.c +++ b/symm/rijndael-base.c @@ -118,6 +118,7 @@ CPU_DISPATCH(static, EMPTY, void, setup, #if CPUFAM_X86 || CPUFAM_AMD64 extern setup__functype rijndael_setup_x86ish_aesni; +extern setup__functype rijndael_setup_x86ish_aesni_avx; #endif #if CPUFAM_ARMEL && HAVE_AS_ARMV8_CRYPTO extern setup__functype rijndael_setup_arm_crypto; @@ -129,6 +130,9 @@ extern setup__functype rijndael_setup_arm64_crypto; static setup__functype *pick_setup(void) { #if CPUFAM_X86 || CPUFAM_AMD64 + DISPATCH_PICK_COND(rijndael_setup, rijndael_setup_x86ish_aesni_avx, + cpu_feature_p(CPUFEAT_X86_AVX) && + cpu_feature_p(CPUFEAT_X86_AESNI)); DISPATCH_PICK_COND(rijndael_setup, rijndael_setup_x86ish_aesni, cpu_feature_p(CPUFEAT_X86_AESNI)); #endif diff --git a/symm/rijndael-x86ish-aesni.S b/symm/rijndael-x86ish-aesni.S index e556aa53..6d9b3b22 100644 --- a/symm/rijndael-x86ish-aesni.S +++ b/symm/rijndael-x86ish-aesni.S @@ -25,20 +25,21 @@ /// MA 02111-1307, USA. ///-------------------------------------------------------------------------- -/// External definitions. +/// Preliminaries. #include "config.h" #include "asm-common.h" + .arch .aes + .extern F(abort) .extern F(rijndael_rcon) + .text + ///-------------------------------------------------------------------------- /// Main code. - .arch .aes - .text - /// The AESNI instructions implement a little-endian version of AES, but /// Catacomb's internal interface presents as big-endian so as to work better /// with things like GCM. We therefore maintain the round keys in @@ -61,6 +62,12 @@ ///-------------------------------------------------------------------------- /// Key setup. +FUNC(rijndael_setup_x86ish_aesni_avx) + vzeroupper // avoid penalty on `legacy' XMM access + endprologue + // and drop through... +ENDFUNC + FUNC(rijndael_setup_x86ish_aesni) #define SI WHOLE(si) @@ -205,16 +212,16 @@ FUNC(rijndael_setup_x86ish_aesni) // Fourth word of the cycle, and seven or eight words of key. Do a // byte substitution. movd xmm0, eax - pshufd xmm0, xmm0, SHUF(2, 1, 0, 3) + pshufd xmm0, xmm0, SHUF(3, 0, 1, 2) aeskeygenassist xmm1, xmm0, 0 movd eax, xmm1 jmp 2f // First word of the cycle. This is the complicated piece. 1: movd xmm0, eax - pshufd xmm0, xmm0, SHUF(0, 3, 2, 1) + pshufd xmm0, xmm0, SHUF(1, 2, 3, 0) aeskeygenassist xmm1, xmm0, 0 - pshufd xmm1, xmm1, SHUF(2, 1, 0, 3) + pshufd xmm1, xmm1, SHUF(3, 0, 1, 2) movd eax, xmm1 xor al, [RCON] inc RCON @@ -365,6 +372,12 @@ ENDFUNC /// Encrypting and decrypting blocks. .macro encdec op, aes, koff + FUNC(rijndael_\op\()_x86ish_aesni_avx) + vzeroupper // avoid XMM penalties + endprologue + // and drop through... + ENDFUNC + FUNC(rijndael_\op\()_x86ish_aesni) #if CPUFAM_X86 diff --git a/symm/rijndael.c b/symm/rijndael.c index 02cfb76b..7db9e012 100644 --- a/symm/rijndael.c +++ b/symm/rijndael.c @@ -83,6 +83,8 @@ CPU_DISPATCH(EMPTY, EMPTY, void, rijndael_dblk, #if CPUFAM_X86 || CPUFAM_AMD64 extern rijndael_eblk__functype rijndael_eblk_x86ish_aesni; extern rijndael_dblk__functype rijndael_dblk_x86ish_aesni; +extern rijndael_eblk__functype rijndael_eblk_x86ish_aesni_avx; +extern rijndael_dblk__functype rijndael_dblk_x86ish_aesni_avx; #endif #if CPUFAM_ARMEL && HAVE_AS_ARMV8_CRYPTO extern rijndael_eblk__functype rijndael_eblk_arm_crypto; @@ -96,6 +98,9 @@ extern rijndael_dblk__functype rijndael_dblk_arm64_crypto; static rijndael_eblk__functype *pick_eblk(void) { #if CPUFAM_X86 || CPUFAM_AMD64 + DISPATCH_PICK_COND(rijndael_eblk, rijndael_eblk_x86ish_aesni_avx, + cpu_feature_p(CPUFEAT_X86_AVX) && + cpu_feature_p(CPUFEAT_X86_AESNI)); DISPATCH_PICK_COND(rijndael_eblk, rijndael_eblk_x86ish_aesni, cpu_feature_p(CPUFEAT_X86_AESNI)); #endif @@ -113,6 +118,9 @@ static rijndael_eblk__functype *pick_eblk(void) static rijndael_dblk__functype *pick_dblk(void) { #if CPUFAM_X86 || CPUFAM_AMD64 + DISPATCH_PICK_COND(rijndael_dblk, rijndael_dblk_x86ish_aesni_avx, + cpu_feature_p(CPUFEAT_X86_AVX) && + cpu_feature_p(CPUFEAT_X86_AESNI)); DISPATCH_PICK_COND(rijndael_dblk, rijndael_dblk_x86ish_aesni, cpu_feature_p(CPUFEAT_X86_AESNI)); #endif diff --git a/symm/salsa20-arm-neon.S b/symm/salsa20-arm-neon.S index 80ed8f06..3b6beb06 100644 --- a/symm/salsa20-arm-neon.S +++ b/symm/salsa20-arm-neon.S @@ -25,18 +25,19 @@ /// MA 02111-1307, USA. ///-------------------------------------------------------------------------- -/// External definitions. +/// Preliminaries. #include "config.h" #include "asm-common.h" -///-------------------------------------------------------------------------- -/// Main.code. - .arch armv7-a .fpu neon + .text +///-------------------------------------------------------------------------- +/// Main.code. + FUNC(salsa20_core_arm_neon) // Arguments are in registers. diff --git a/symm/salsa20-arm64.S b/symm/salsa20-arm64.S index 821548e1..864c63c1 100644 --- a/symm/salsa20-arm64.S +++ b/symm/salsa20-arm64.S @@ -25,17 +25,18 @@ /// MA 02111-1307, USA. ///-------------------------------------------------------------------------- -/// External definitions. +/// Preliminaries. #include "config.h" #include "asm-common.h" -///-------------------------------------------------------------------------- -/// Main.code. - .arch armv8-a + .text +///-------------------------------------------------------------------------- +/// Main.code. + FUNC(salsa20_core_arm64) // Arguments are in registers. diff --git a/symm/salsa20-core.h b/symm/salsa20-core.h index b27f2220..e64e7331 100644 --- a/symm/salsa20-core.h +++ b/symm/salsa20-core.h @@ -164,8 +164,8 @@ */ #define SALSA20_PREPBUF(ctx, a) do { \ int _i; \ - for (_i = 0; _i < 16; _i++) STORE32_L((ctx)->buf + 4*_i, (a)[_i]); \ - (ctx)->bufi = 0; \ + for (_i = 0; _i < 16; _i++) STORE32_L((ctx)->b + 4*_i, (a)[_i]); \ + (ctx)->off = 0; \ } while (0) /* Write at most @n@ bytes of buffered output from the context @ctx@ to the @@ -174,12 +174,13 @@ * @n@ is decreased appropriately. */ #define SALSA20_OUTBUF(ctx, d, s, n) do { \ - size_t _n = (n), _left = SALSA20_OUTSZ - (ctx)->bufi; \ - if (_n > _left) _n = _left; \ - (n) -= _n; \ - if (!(d)) (ctx)->bufi += _n; \ - else if (s) while (_n--) *(d)++ = (ctx)->buf[(ctx)->bufi++] ^ *(s)++; \ - else while (_n--) *(d)++ = (ctx)->buf[(ctx)->bufi++]; \ + const octet *_p = (ctx)->b + (ctx)->off; \ + size_t _n = (n); \ + \ + (ctx)->off += _n; \ + if (!(d)) /* nothing to do */; \ + else if (!(s)) { memcpy((d), _p, _n); (d) += _n; } \ + else while (_n--) *(d)++ = *(s)++ ^ *_p++; \ } while (0) /*----- Variants and naming -----------------------------------------------*/ diff --git a/symm/salsa20-poly1305.c b/symm/salsa20-poly1305.c new file mode 100644 index 00000000..201a0832 --- /dev/null +++ b/symm/salsa20-poly1305.c @@ -0,0 +1,85 @@ +/* -*-c-*- + * + * AEAD schemes based on Salsa20 and Poly1305 + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software: you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "latinpoly-def.h" +#include "salsa20.h" + +/*----- Main code ---------------------------------------------------------*/ + +LATINPOLY_DEF(salsa20, salsa20, "salsa20") +LATINPOLY_DEF(salsa2012, salsa20, "salsa20/12") +LATINPOLY_DEF(salsa208, salsa20, "salsa20/8") + +/*----- Test rig ----------------------------------------------------------*/ + +#ifdef TEST_RIG + +#include +#include +#include "latinpoly-test.h" + +static int check_salsa20_poly1305(dstr *v) + { return latinpoly_test(&salsa20_poly1305, v); } +static int check_salsa2012_poly1305(dstr *v) + { return latinpoly_test(&salsa2012_poly1305, v); } +static int check_salsa208_poly1305(dstr *v) + { return latinpoly_test(&salsa208_poly1305, v); } +static int check_salsa20_naclbox(dstr *v) + { return latinpoly_test(&salsa20_naclbox, v); } +static int check_salsa2012_naclbox(dstr *v) + { return latinpoly_test(&salsa2012_naclbox, v); } +static int check_salsa208_naclbox(dstr *v) + { return latinpoly_test(&salsa208_naclbox, v); } + +static const test_chunk tests[] = { + { "salsa20-poly1305", check_salsa20_poly1305, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { "salsa20/12-poly1305", check_salsa2012_poly1305, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { "salsa20/8-poly1305", check_salsa208_poly1305, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { "salsa20-naclbox", check_salsa20_naclbox, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { "salsa20/12-naclbox", check_salsa2012_naclbox, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { "salsa20/8-nacblox", check_salsa208_naclbox, + { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } }, + { 0, 0, { 0 } } +#undef TEST +}; + +int main(int argc, char *argv[]) +{ + ego(argv[0]); + test_run(argc, argv, tests, SRCDIR"/t/salsa20"); + return (0); +} + +#endif +/*----- That's all, folks -------------------------------------------------*/ diff --git a/symm/salsa20-x86ish-sse2.S b/symm/salsa20-x86ish-sse2.S index 7d8e2e38..5dc9c17c 100644 --- a/symm/salsa20-x86ish-sse2.S +++ b/symm/salsa20-x86ish-sse2.S @@ -25,16 +25,24 @@ /// MA 02111-1307, USA. ///-------------------------------------------------------------------------- -/// External definitions. +/// Preliminaries. #include "config.h" #include "asm-common.h" + .text + ///-------------------------------------------------------------------------- /// Main code. - .arch pentium4 - .text +FUNC(salsa20_core_x86ish_avx) + .arch .avx + vzeroupper + endprologue + // drop through... +ENDFUNC + + .arch pentium4 FUNC(salsa20_core_x86ish_sse2) @@ -61,7 +69,7 @@ FUNC(salsa20_core_x86ish_sse2) # define SAVE3 [esp + 16] pushreg ebp - setfp ebp + setfp sub esp, 32 mov IN, [ebp + 12] mov OUT, [ebp + 16] @@ -172,7 +180,7 @@ FUNC(salsa20_core_x86ish_sse2) // d ^= (c + b) <<< 13 movdqa xmm4, xmm2 paddd xmm4, xmm1 - pshufd xmm1, xmm1, SHUF(2, 1, 0, 3) + pshufd xmm1, xmm1, SHUF(3, 0, 1, 2) movdqa xmm5, xmm4 pslld xmm4, 13 psrld xmm5, 19 @@ -181,9 +189,9 @@ FUNC(salsa20_core_x86ish_sse2) // a ^= (d + c) <<< 18 movdqa xmm4, xmm3 - pshufd xmm3, xmm3, SHUF(0, 3, 2, 1) + pshufd xmm3, xmm3, SHUF(1, 2, 3, 0) paddd xmm4, xmm2 - pshufd xmm2, xmm2, SHUF(1, 0, 3, 2) + pshufd xmm2, xmm2, SHUF(2, 3, 0, 1) movdqa xmm5, xmm4 pslld xmm4, 18 psrld xmm5, 14 @@ -227,7 +235,7 @@ FUNC(salsa20_core_x86ish_sse2) // d ^= (c + b) <<< 13 movdqa xmm4, xmm2 paddd xmm4, xmm3 - pshufd xmm3, xmm3, SHUF(2, 1, 0, 3) + pshufd xmm3, xmm3, SHUF(3, 0, 1, 2) movdqa xmm5, xmm4 pslld xmm4, 13 psrld xmm5, 19 @@ -236,9 +244,9 @@ FUNC(salsa20_core_x86ish_sse2) // a ^= (d + c) <<< 18 movdqa xmm4, xmm1 - pshufd xmm1, xmm1, SHUF(0, 3, 2, 1) + pshufd xmm1, xmm1, SHUF(1, 2, 3, 0) paddd xmm4, xmm2 - pshufd xmm2, xmm2, SHUF(1, 0, 3, 2) + pshufd xmm2, xmm2, SHUF(2, 3, 0, 1) movdqa xmm5, xmm4 pslld xmm4, 18 psrld xmm5, 14 @@ -262,9 +270,9 @@ FUNC(salsa20_core_x86ish_sse2) // input. This can be done by juggling values in registers, with the // following fancy footwork: some row rotations, a transpose, and // some more rotations. - pshufd xmm1, xmm1, SHUF(2, 1, 0, 3) // 3, 4, 9, 14 - pshufd xmm2, xmm2, SHUF(1, 0, 3, 2) // 2, 7, 8, 13 - pshufd xmm3, xmm3, SHUF(0, 3, 2, 1) // 1, 6, 11, 12 + pshufd xmm1, xmm1, SHUF(3, 0, 1, 2) // 3, 4, 9, 14 + pshufd xmm2, xmm2, SHUF(2, 3, 0, 1) // 2, 7, 8, 13 + pshufd xmm3, xmm3, SHUF(1, 2, 3, 0) // 1, 6, 11, 12 movdqa xmm4, xmm0 movdqa xmm5, xmm3 @@ -280,9 +288,9 @@ FUNC(salsa20_core_x86ish_sse2) punpckhdq xmm1, xmm3 // 5, 6, 7, 4 punpckhdq xmm2, xmm5 // 15, 12, 13, 14 - pshufd xmm1, xmm1, SHUF(2, 1, 0, 3) // 4, 5, 6, 7 - pshufd xmm4, xmm4, SHUF(1, 0, 3, 2) // 8, 9, 10, 11 - pshufd xmm2, xmm2, SHUF(0, 3, 2, 1) // 12, 13, 14, 15 + pshufd xmm1, xmm1, SHUF(3, 0, 1, 2) // 4, 5, 6, 7 + pshufd xmm4, xmm4, SHUF(2, 3, 0, 1) // 8, 9, 10, 11 + pshufd xmm2, xmm2, SHUF(1, 2, 3, 0) // 12, 13, 14, 15 // Finally we have to write out the result. movdqu [OUT + 0], xmm0 diff --git a/symm/salsa20.c b/symm/salsa20.c index 03fcf469..0303d8bd 100644 --- a/symm/salsa20.c +++ b/symm/salsa20.c @@ -39,6 +39,7 @@ #include "grand.h" #include "keysz.h" #include "paranoia.h" +#include "rsvr.h" #include "salsa20.h" #include "salsa20-core.h" @@ -72,6 +73,7 @@ static void simple_core(unsigned r, const salsa20_matrix src, #if CPUFAM_X86 || CPUFAM_AMD64 extern core__functype salsa20_core_x86ish_sse2; +extern core__functype salsa20_core_x86ish_avx; #endif #if CPUFAM_ARMEL @@ -85,6 +87,8 @@ extern core__functype salsa20_core_arm64; static core__functype *pick_core(void) { #if CPUFAM_X86 || CPUFAM_AMD64 + DISPATCH_PICK_COND(salsa20_core, salsa20_core_x86ish_avx, + cpu_feature_p(CPUFEAT_X86_AVX)); DISPATCH_PICK_COND(salsa20_core, salsa20_core_x86ish_sse2, cpu_feature_p(CPUFEAT_X86_SSE2)); #endif @@ -158,6 +162,8 @@ static void populate(salsa20_matrix a, const void *key, size_t ksz) /*----- Salsa20 implementation --------------------------------------------*/ +static const octet zerononce[XSALSA20_NONCESZ]; + /* --- @salsa20_init@ --- * * * Arguments: @salsa20_ctx *ctx@ = context to fill in @@ -173,8 +179,6 @@ static void populate(salsa20_matrix a, const void *key, size_t ksz) void salsa20_init(salsa20_ctx *ctx, const void *key, size_t ksz, const void *nonce) { - static const octet zerononce[SALSA20_NONCESZ]; - populate(ctx->a, key, ksz); salsa20_setnonce(ctx, nonce ? nonce : zerononce); } @@ -230,7 +234,7 @@ void salsa20_seek(salsa20_ctx *ctx, unsigned long i) void salsa20_seeku64(salsa20_ctx *ctx, kludge64 i) { ctx->a[8] = LO64(i); ctx->a[5] = HI64(i); - ctx->bufi = SALSA20_OUTSZ; + ctx->off = 0; } void salsa20_seek_ietf(salsa20_ctx *ctx, uint32 i) @@ -270,6 +274,8 @@ uint32 salsa20_tell_ietf(salsa20_ctx *ctx) * to @dest@. */ +static const rsvr_policy policy = { 0, SALSA20_OUTSZ, SALSA20_OUTSZ }; + #define SALSA20_ENCRYPT(r, ctx, src, dest, sz) \ SALSA20_DECOR(salsa20, r, _encrypt)(ctx, src, dest, sz) #define DEFENCRYPT(r) \ @@ -279,41 +285,40 @@ uint32 salsa20_tell_ietf(salsa20_ctx *ctx) salsa20_matrix b; \ const octet *s = src; \ octet *d = dest; \ - size_t n; \ + rsvr_plan plan; \ kludge64 pos, delta; \ \ - SALSA20_OUTBUF(ctx, d, s, sz); \ - if (!sz) return; \ - \ - if (!dest) { \ - n = sz/SALSA20_OUTSZ; \ - pos = salsa20_tellu64(ctx); \ - ASSIGN64(delta, n); \ - ADD64(pos, pos, delta); \ - salsa20_seeku64(ctx, pos); \ - sz = sz%SALSA20_OUTSZ; \ - } else if (!src) { \ - while (sz >= SALSA20_OUTSZ) { \ - core(r, ctx->a, b); \ - SALSA20_STEP(ctx->a); \ - SALSA20_GENFULL(b, d); \ - sz -= SALSA20_OUTSZ; \ + rsvr_mkplan(&plan, &policy, ctx->off, sz); \ + \ + if (plan.head) { \ + if (!ctx->off) { \ + core(r, ctx->a, b); SALSA20_STEP(ctx->a); \ + SALSA20_PREPBUF(ctx, b); \ } \ - } else { \ - while (sz >= SALSA20_OUTSZ) { \ - core(r, ctx->a, b); \ - SALSA20_STEP(ctx->a); \ - SALSA20_MIXFULL(b, d, s); \ - sz -= SALSA20_OUTSZ; \ + SALSA20_OUTBUF(ctx, d, s, plan.head); \ + } \ + \ + ctx->off -= plan.from_rsvr; \ + \ + if (!d) { \ + if (plan.from_input) { \ + pos = salsa20_tellu64(ctx); \ + ASSIGN64(delta, plan.from_input/SALSA20_OUTSZ); \ + ADD64(pos, pos, delta); \ + salsa20_seeku64(ctx, pos); \ } \ + } else if (!s) while (plan.from_input) { \ + core(r, ctx->a, b); SALSA20_STEP(ctx->a); \ + SALSA20_GENFULL(b, d); plan.from_input -= SALSA20_OUTSZ; \ + } else while (plan.from_input) { \ + core(r, ctx->a, b); SALSA20_STEP(ctx->a); \ + SALSA20_MIXFULL(b, d, s); plan.from_input -= SALSA20_OUTSZ; \ } \ \ - if (sz) { \ - core(r, ctx->a, b); \ - SALSA20_STEP(ctx->a); \ + if (plan.tail) { \ + core(r, ctx->a, b); SALSA20_STEP(ctx->a); \ SALSA20_PREPBUF(ctx, b); \ - SALSA20_OUTBUF(ctx, d, s, sz); \ - assert(!sz); \ + SALSA20_OUTBUF(ctx, d, s, plan.tail); \ } \ } SALSA20_VARS(DEFENCRYPT) @@ -418,8 +423,6 @@ SALSA20_VARS(DEFHSALSA20) void XSALSA20_INIT(r, XSALSA20_CTX(r) *ctx, \ const void *key, size_t ksz, const void *nonce) \ { \ - static const octet zerononce[XSALSA20_NONCESZ]; \ - \ populate(ctx->k, key, ksz); \ ctx->s.a[ 0] = SALSA20_A256; \ ctx->s.a[ 1] = SALSA20_B256; \ diff --git a/symm/salsa20.h b/symm/salsa20.h index 317a34c1..7f3059ef 100644 --- a/symm/salsa20.h +++ b/symm/salsa20.h @@ -64,8 +64,8 @@ typedef uint32 salsa20_matrix[16]; typedef struct salsa20_ctx { salsa20_matrix a; - octet buf[SALSA20_OUTSZ]; - size_t bufi; + octet b[SALSA20_OUTSZ]; + unsigned off; } salsa20_ctx; #define XSALSA20_DEFCTX(name) \ diff --git a/symm/seal.c b/symm/seal.c index 0ba56c0e..a4a0a3f8 100644 --- a/symm/seal.c +++ b/symm/seal.c @@ -62,35 +62,37 @@ static void sealgamma(uint32 *p, size_t sz, const void *k, unsigned i) { uint32 buf[80] = { 0 }; const octet *kk = k; - uint32 aa = LOAD32(kk); - uint32 bb = LOAD32(kk + 4); - uint32 cc = LOAD32(kk + 8); - uint32 dd = LOAD32(kk + 12); - uint32 ee = LOAD32(kk + 16); + uint32 a, aa = LOAD32(kk); + uint32 b, bb = LOAD32(kk + 4); + uint32 c, cc = LOAD32(kk + 8); + uint32 d, dd = LOAD32(kk + 12); + uint32 e, ee = LOAD32(kk + 16); + + unsigned skip = i%5; + uint32 x; + int j; - unsigned skip = i % 5; i /= 5; /* --- While there's hashing to do, do hashing --- */ while (sz) { - uint32 a = aa, b = bb, c = cc, d = dd, e = ee; - int j; + a = aa, b = bb, c = cc, d = dd, e = ee; /* --- Initialize and expand the buffer --- */ buf[0] = i++; for (j = 16; j < 80; j++) { - uint32 x = buf[j - 3] ^ buf[j - 8] ^ buf[j - 14] ^ buf[j - 16]; + x = buf[j - 3] ^ buf[j - 8] ^ buf[j - 14] ^ buf[j - 16]; buf[j] = ROL32(x, 1); } /* --- Definitions for round functions --- */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define F(x, y, z) (((x)&(y)) | (~(x)&(z))) #define G(x, y, z) ((x) ^ (y) ^ (z)) -#define H(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) (((x)&(y)) | ((x)&(z)) | ((y)&(z))) #define T(v, w, x, y, z, i, f, k) do { \ uint32 _x; \ @@ -109,14 +111,10 @@ static void sealgamma(uint32 *p, size_t sz, const void *k, unsigned i) * Since this isn't doing bulk hashing, do it the easy way. */ - for (j = 0; j < 20; j++) - FF(a, b, c, d, e, j); - for (j = 20; j < 40; j++) - GG(a, b, c, d, e, j); - for (j = 40; j < 60; j++) - HH(a, b, c, d, e, j); - for (j = 60; j < 80; j++) - II(a, b, c, d, e, j); + for (j = 0; j < 20; j++) FF(a, b, c, d, e, j); + for (j = 20; j < 40; j++) GG(a, b, c, d, e, j); + for (j = 40; j < 60; j++) HH(a, b, c, d, e, j); + for (j = 60; j < 80; j++) II(a, b, c, d, e, j); /* --- Do the chaining at the end --- */ @@ -125,17 +123,12 @@ static void sealgamma(uint32 *p, size_t sz, const void *k, unsigned i) /* --- Write to the output buffer --- */ switch (skip) { - case 0: - if (sz) { *p++ = a; sz--; } - case 1: - if (sz) { *p++ = b; sz--; } - case 2: - if (sz) { *p++ = c; sz--; } - case 3: - if (sz) { *p++ = d; sz--; } - case 4: - if (sz) { *p++ = e; sz--; } - skip = 0; + case 0: if (sz) { *p++ = a; sz--; } + case 1: if (sz) { *p++ = b; sz--; } + case 2: if (sz) { *p++ = c; sz--; } + case 3: if (sz) { *p++ = d; sz--; } + case 4: if (sz) { *p++ = e; sz--; } + skip = 0; } } } @@ -155,16 +148,12 @@ static void sealgamma(uint32 *p, size_t sz, const void *k, unsigned i) void seal_initkey(seal_key *k, const void *buf, size_t sz) { + sha_ctx h; + /* --- Hash the key if it's the wrong size --- */ - if (sz == SHA_HASHSZ) - memcpy(k->k, buf, sizeof(k->k)); - else { - sha_ctx c; - sha_init(&c); - sha_hash(&c, buf, sz); - sha_done(&c, k->k); - } + if (sz == SHA_HASHSZ) memcpy(k->k, buf, sizeof(k->k)); + else { sha_init(&h); sha_hash(&h, buf, sz); sha_done(&h, k->k); } /* --- Expand the key to fit the various tables --- */ @@ -208,14 +197,14 @@ static void seal_reset(seal_ctx *c) /* --- Ensure that everything is sufficiently diffused --- */ - p = A & 0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9); - p = B & 0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9); - p = C & 0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9); - p = D & 0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9); - p = A & 0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9); - p = B & 0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9); - p = C & 0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9); - p = D & 0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9); + p = A&0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9); + p = B&0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9); + p = C&0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9); + p = D&0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9); + p = A&0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9); + p = B&0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9); + p = C&0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9); + p = D&0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9); /* --- Write out some context --- */ @@ -223,10 +212,10 @@ static void seal_reset(seal_ctx *c) /* --- Diffuse some more --- */ - p = A & 0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9); - p = B & 0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9); - p = C & 0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9); - p = D & 0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9); + p = A&0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9); + p = B&0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9); + p = C&0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9); + p = D&0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9); /* --- Write out the magic numbers --- */ @@ -253,7 +242,7 @@ void seal_initctx(seal_ctx *c, seal_key *k, uint32 n) c->l = 0; c->r = k->r; c->ri = 0x2000 + SEAL_R; - c->qsz = 0; + c->off = 16; seal_reset(c); } @@ -274,34 +263,32 @@ void seal_initctx(seal_ctx *c, seal_key *k, uint32 n) void seal_encrypt(seal_ctx *c, const void *src, void *dest, size_t sz) { + seal_key *k = c->k; const octet *s = src; - octet *d = dest; + octet *d = dest, *p; + uint32 A = c->a, B = c->b, C = c->c, D = c->d; + uint32 n1 = c->n1, n2 = c->n2, n3 = c->n3, n4 = c->n4; + uint32 aa, bb, cc, dd; + unsigned i, j; + unsigned P, Q; /* --- Expect a big dollop of bytes --- */ - if (sz > c->qsz) { - seal_key *k = c->k; - uint32 A = c->a, B = c->b, C = c->c, D = c->d; - uint32 n1 = c->n1, n2 = c->n2, n3 = c->n3, n4 = c->n4; - uint32 aa, bb, cc, dd; - unsigned j = c->i; - - /* --- Empty the queue first --- */ - - if (c->qsz) { - if (d) { - unsigned i; - octet *p = c->q + sizeof(c->q) - c->qsz; - for (i = 0; i < c->qsz; i++) - *d++ = (s ? *s++ ^ *p++ : *p++); - } - sz -= c->qsz; + if (sz > 16 - c->off) { + j = c->i; + + /* --- Drain the buffer first --- */ + + if (c->off < 16) { + p = c->buf + c->off; sz -= 16 - c->off; + if (!d) /* nothing to do* */; + else if (!s) memcpy(d, p, 16 - c->off); + else for (i = c->off; i < 16; i++) *d++ = *s++ ^ *p++; } /* --- Main sequence --- */ for (;;) { - unsigned P, Q; /* --- Reset if we've run out of steam on this iteration --- */ @@ -314,74 +301,63 @@ void seal_encrypt(seal_ctx *c, const void *src, void *dest, size_t sz) /* --- Make some new numbers --- */ - P = A & 0x7fc; B += k->t[P >> 2]; A = ROR32(A, 9); B ^= A; - Q = B & 0x7fc; C ^= k->t[Q >> 2]; B = ROR32(B, 9); C += B; - P = (P + C) & 0x7fc; D += k->t[P >> 2]; C = ROR32(C, 9); D ^= C; - Q = (Q + D) & 0x7fc; A ^= k->t[Q >> 2]; D = ROR32(D, 9); A += D; - P = (P + A) & 0x7fc; B ^= k->t[P >> 2]; A = ROR32(A, 9); - Q = (Q + B) & 0x7fc; C += k->t[Q >> 2]; B = ROR32(B, 9); - P = (P + C) & 0x7fc; D ^= k->t[P >> 2]; C = ROR32(C, 9); - Q = (Q + D) & 0x7fc; A += k->t[Q >> 2]; D = ROR32(D, 9); + P = A&0x7fc; B += k->t[P >> 2]; A = ROR32(A, 9); B ^= A; + Q = B&0x7fc; C ^= k->t[Q >> 2]; B = ROR32(B, 9); C += B; + P = (P + C)&0x7fc; D += k->t[P >> 2]; C = ROR32(C, 9); D ^= C; + Q = (Q + D)&0x7fc; A ^= k->t[Q >> 2]; D = ROR32(D, 9); A += D; + P = (P + A)&0x7fc; B ^= k->t[P >> 2]; A = ROR32(A, 9); + Q = (Q + B)&0x7fc; C += k->t[Q >> 2]; B = ROR32(B, 9); + P = (P + C)&0x7fc; D ^= k->t[P >> 2]; C = ROR32(C, 9); + Q = (Q + D)&0x7fc; A += k->t[Q >> 2]; D = ROR32(D, 9); /* --- Remember the output and set up the next round --- */ - aa = B + k->s[j + 0]; - bb = C ^ k->s[j + 1]; - cc = D + k->s[j + 2]; - dd = A ^ k->s[j + 3]; + aa = B + k->s[j + 0]; bb = C ^ k->s[j + 1]; + cc = D + k->s[j + 2]; dd = A ^ k->s[j + 3]; j += 4; - if (j & 4) - A += n1, B += n2, C ^= n1, D ^= n2; - else - A += n3, B += n4, C ^= n3, D ^= n4; + if (j&4) { A += n1; B += n2; C ^= n1; D ^= n2; } + else { A += n3; B += n4; C ^= n3; D ^= n4; } /* --- Bail out here if we need to do buffering --- */ - if (sz < 16) - break; + if (sz < 16) break; /* --- Write the next 16 bytes --- */ - if (d) { + if (!d) /* nothing to do */; + else { if (s) { - aa ^= LOAD32_L(s + 0); - bb ^= LOAD32_L(s + 4); - cc ^= LOAD32_L(s + 8); - dd ^= LOAD32_L(s + 12); + aa ^= LOAD32_L(s + 0); bb ^= LOAD32_L(s + 4); + cc ^= LOAD32_L(s + 8); dd ^= LOAD32_L(s + 12); s += 16; } - STORE32_L(d + 0, aa); - STORE32_L(d + 4, bb); - STORE32_L(d + 8, cc); - STORE32_L(d + 12, dd); + STORE32_L(d + 0, aa); STORE32_L(d + 4, bb); + STORE32_L(d + 8, cc); STORE32_L(d + 12, dd); d += 16; } sz -= 16; } - /* --- Write the new queue --- */ + /* --- Write the new buffer --- */ - STORE32_L(c->q + 0, aa); - STORE32_L(c->q + 4, bb); - STORE32_L(c->q + 8, cc); - STORE32_L(c->q + 12, dd); - c->qsz = 16; + STORE32_L(c->buf + 0, aa); + STORE32_L(c->buf + 4, bb); + STORE32_L(c->buf + 8, cc); + STORE32_L(c->buf + 12, dd); + c->off = 0; c->a = A; c->b = B; c->c = C; c->d = D; c->i = j; } - /* --- Deal with the rest from the queue --- */ + /* --- Deal with the rest from the buffer --- */ if (sz) { - unsigned i; - octet *p = c->q + sizeof(c->q) - c->qsz; - if (d) { - for (i = 0; i < sz; i++) - *d++ = (s ? *s++ ^ *p++ : *p++); - } - c->qsz -= sz; + p = c->buf + c->off; c->off += sz; + if (!d) /* nothing to do* */; + else if (!s) memcpy(d, p, sz); + else for (i = 0; i < sz; i++) *d++ = *s++ ^ *p++; } } @@ -405,10 +381,7 @@ static gcipher *ginit(const void *k, size_t sz) } static void gencrypt(gcipher *c, const void *s, void *t, size_t sz) -{ - gctx *g = (gctx *)c; - seal_encrypt(&g->cc, s, t, sz); -} + { gctx *g = (gctx *)c; seal_encrypt(&g->cc, s, t, sz); } static void gsetiv(gcipher *c, const void *iv) { @@ -418,11 +391,7 @@ static void gsetiv(gcipher *c, const void *iv) } static void gdestroy(gcipher *c) -{ - gctx *g = (gctx *)c; - BURN(*g); - S_DESTROY(g); -} + { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); } static const gcipher_ops gops = { &seal, @@ -443,11 +412,7 @@ typedef struct grctx { } grctx; static void grdestroy(grand *r) -{ - grctx *g = (grctx *)r; - BURN(*g); - S_DESTROY(g); -} + { grctx *g = (grctx *)r; BURN(*g); S_DESTROY(g); } static int grmisc(grand *r, unsigned op, ...) { @@ -520,10 +485,7 @@ static uint32 grword(grand *r) } static void grfill(grand *r, void *p, size_t sz) -{ - grctx *g = (grctx *)r; - seal_encrypt(&g->cc, 0, p, sz); -} + { grctx *g = (grctx *)r; seal_encrypt(&g->cc, 0, p, sz); } static const grand_ops grops = { "seal", diff --git a/symm/seal.h b/symm/seal.h index 875994e8..adb17ab1 100644 --- a/symm/seal.h +++ b/symm/seal.h @@ -76,8 +76,8 @@ typedef struct seal_ctx { uint32 a, b, c, d; /* Current chaining variables */ uint32 n1, n2, n3, n4; /* Increments for the variables */ unsigned i; /* Index into current iteration */ - octet q[16]; /* Output buffer */ - unsigned qsz; /* Number of bytes in the buffer */ + octet buf[16]; /* Output buffer */ + unsigned off; /* Offset into the buffer */ uint32 rbuf[SEAL_R]; /* Buffer for later magic */ } seal_ctx; diff --git a/symm/stub.h.in b/symm/stub.h.in index c29de5bb..686b5741 100644 --- a/symm/stub.h.in +++ b/symm/stub.h.in @@ -10,7 +10,7 @@ #ifndef CATACOMB_@{name:u:c}_H #define CATACOMB_@{name:u:c}_H -#ifndef CATACOMB_@{base:u}_H +#ifndef CATACOMB_@{base:u:c}_H # include "@base.h" #endif diff --git a/symm/t/blowfish b/symm/t/blowfish index 449f9678..a49688c2 100644 --- a/symm/t/blowfish +++ b/symm/t/blowfish @@ -117,3 +117,933 @@ blowfish { f0e1d2c3b4a5968778695a4b3c2d1e0f0011223344556677 fedcba9876543210 05044b62fa52d080; } + +blowfish-cmac { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa906 + "" + 233f464f6f4fed40; + 0d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d + 1f + f80086d1f74c3c25; + 337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e + 6057acc87638f508046733d9ff61cdbda3b3e9878731ebfe + 88141768f1834980; + dd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450 + 727a9b542cde52ebfda19d0ccc520f215eb57b + 8b2e3c8554c039c5; + b3a4f3ebbbb18ac6c95a97 + "" + 992c2d7bae553fa1; + a48030370c33d090c54215 + ab + 3ef759021e0bd2c2; + d6b3ad54efc9a38378c5b9 + 3bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac + 7ef83257367f4dcf; + 26afa3349829b94586306f + ed54154f8f28523c03d4de1600157846b710ee + 595b0c57e4ecd664; + 72807a2219 + "" + c17ded27f35e843b; + bfb474fd71 + d8 + 063d632b053cfb61; + 91f24bb65d + 1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbac + aefe8538008cd029; + a48b77dba1 + 89196d1ebba10b0467cb9fc2712a199e533fa9 + 296073d2f0263834; + 156308cdec3f768281e040a9b9a222bd689aef66f5306c + "" + fc5dcde84c290e8e; + eb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb + 0b + f0e70394d6b143c9; + ad7d95214ade49cb3b6f5fe8368131115c037ba323fe1d + c8151784873f0eb5b647da6794c18b5337685a96ed65b9ac + a9be9c5120820347; + a338527ef19b09c063c46f88de9fd41e72d7b97e23e6ea + bdff3bcd211499268878dbf30f1dad89d4b9b1 + a54fb7e239aeec4c; +} + +blowfish-ccm { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa906 + 0d2d4b + "" + "" + "" + c25c474f; + 6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f + 29549e + 6b + "" + "" + 57a5a9c3; + 0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638 + f50804 + "" + 67 + f4 + 62383997; + 33d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7 + f65b000961 + 040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f + 215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5 + 71ecbda26749ad4076aec1c63db0b7dcec21cf7a4861d69c + fb8186360d67254d; + 4215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28 + 523c03d4de + 1600157846b710ee72807a2219bfb474fd71d8 + 91f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbac + fa1e4cf72580563be4989ec3530f64fe6b897d54ed59da433615948331 + 93d5c6d564e86652; + a48b77dba189196d1ebba1 + 0b0467 + "" + "" + "" + 63379d2c; + cb9fc2712a199e533fa915 + 6308cd + ec + "" + "" + 0a7f855f; + 3f768281e040a9b9a222bd + 689aef + "" + 66 + 96 + d2ba74d4; + f5306ceb0c6b08ac8b0a22 + 260c571b4a + 42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe836 + 8131115c037ba323fe1dc8151784873f0eb5b647da6794c1 + 458b929afd86f86db6c134400b0d1522882e10660e925b2d + 0c69aa29dde98aa1; + 8b5337685a96ed65b9aca3 + 38527ef19b + 09c063c46f88de9fd41e72d7b97e23e6eabdff + 3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952 + 5b680782d41f7d46c44d3811c313892f486f1597ed60dc10f15d1c43d5 + 327a56fa715955fc; + d22bb02d71 + 00b8b6 + "" + "" + "" + 6eaeedf7; + 49377d20a8 + f08345 + 5b + "" + "" + eb64c104; + 663e4ee131 + 5f3c8f + "" + 2a + 22 + 87151792; + ebfa921451 + dcd1af5813 + b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584 + b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16 + 58be2a1ed2225be8ef09f86202a312b01b829eb7e326b926 + 88f7ac759bdd6989; + cb16c2e815 + f422cdf0c8 + e30308be3c31e6bc58c0b7cadcb658b970e474 + 79a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70 + 49058d3fde34557441cc9b3e231c87043a5741c3eb99cc2bc58b5f4b6f + 87c25970fcee3bba; + e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784 + e0c6f2 + "" + "" + "" + 16bd95ba; + 1195a3b9f4ae985511265febd11c164720eef9eb1c8dd0 + b00951 + f2 + "" + "" + 44763b0a; + 84649016ed00456331854bc78bf43966eb0cfa9138ddc3 + 990844 + "" + 56 + b4 + 8072f963; + 08fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d1 + 26b807e6da + a089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973 + a8cd190107314717a77456f3ff669c732b58db8f48af65f7 + 86876ace214551f65de8ef07460bc5c70638989bc14365c7 + 1347b1b46e131d8e; + cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b387 + 66fc69f6a9 + f2c0945ffd505003cc0cae9ce021a5f1fa4ffa + 91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff67785 + 0f2d12a0832a56f1640d37b17c901d899e2fa4678c867664380cd31062 + 596d1ddc3b997e5a; +} + +blowfish-eax { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa906 + "" + "" + "" + "" + a6e2fbebaf974200; + 0d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d + 1f + "" + "" + "" + 4cc58c2f4cf91137; + 337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e + "" + 60 + "" + "" + c35fc08fda46f599; + 57acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb95295 + "" + "" + 33 + 9c + b7c0dcb87a8b86c9; + 966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030 + 370c33d090c54215 + abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb6 + 48e27fff63102758fe2b69ac26afa3349829b94586306fed + 783ab2ee6ea73b63906caf73ceb4376b2e9ebee34fc490c5 + 3fff7a36718ab82c; + 54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df + 9fcbaca48b77db + a189196d1ebba10b0467cb9fc2712a199e533f + a9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac + 43bfef92d8c8ba5641fb2523e92ef24d60a41da2e8bb3112aee7b80ce3 + 07ad2ca904227df7; + 8b0a22260c571b4a42bb8f + "" + "" + "" + "" + bd94df689662060a; + db233bfa6a5cfb0bad7d95 + 21 + "" + "" + "" + a43ffffe35e1b8a4; + 4ade49cb3b6f5fe8368131 + "" + 11 + "" + "" + d32da332498a6950; + 5c037ba323fe1dc8151784 + "" + "" + 87 + 12 + 0943c4cb5e3fc7eb; + 3f0eb5b647da6794c18b53 + 37685a96ed65b9ac + a338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabd + ff3bcd211499268878dbf30f1dad89d4b9b12012e4713df4 + aebee82a01e138a7229636ee0eb746f6ce13584936f56bb4 + 5bddd65c9a111ec7; + 6795630e7952d22bb02d71 + 00b8b649377d20 + a8f083455b663e4ee1315f3c8f2aebfa921451 + dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584 + 8a298eafedf8c1e183dfa50569cda59c9f93e56fde173e750e2fa185c7 + 78a05a55f474688a; + b7c5e61766 + "" + "" + "" + "" + 6e8da28b2d84682a; + 9c0f16e398 + 15 + "" + "" + "" + a6660ae3f78c52b7; + d4e9cfce3e + "" + d1 + "" + "" + caa08d52fd0d87cf; + ecdf3d264a + "" + "" + 7f + b7 + af92632b8a903cfd; + 16cb16c2e8 + 15f422cdf0c8e303 + 08be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69 + a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e + 773aeb0f1ffbc8b9f0a642275761a79598ab37c4a531e157 + 7b4483789e1768fc; + 98ef1f0446 + b42fb144d44b6d + 00f06dc188d472a784e0c6f21195a3b9f4ae98 + 5511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331 + 08d772c882d1d700f980b349e40c3cb563743f62b966fe38ce39831c37 + 62662279f37c6a9b; + 854bc78bf43966eb0cfa9138ddc39908445608fe95e81c + "" + "" + "" + "" + 99eb415cd27dfb9d; + 2533e31c9c1a9851bc2810d858cbbc8424d126b807e6da + a0 + "" + "" + "" + c90ad3bb5ff737a9; + 89c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973 + "" + a8 + "" + "" + dc32c7a1d4f99131; + cd190107314717a77456f3ff669c732b58db8f48af65f7 + "" + "" + cc + 86 + 5a32c09bf86a0f69; + 9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766 + fc69f6a9f2c0945f + fd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b + 9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf127 + c9d09215bfda6368733b83186710d656bd900f072a02173d + 1e35ed44860e1cb0; + 0485b203a3c1c4c967c0a458cb948bdd409b687fa3a682 + 7b480aa3a4c84c + ef64f6c9b53bf8f957f4b03cf43e89957f9a3e + 8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf + 1b485cb8f21d2744e6fdb19989d90693a8d2b935d0eae05facba546e91 + 8b86611191b4bdf3; +} + +blowfish-gcm { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa906 + "" + "" + "" + "" + 6b5ff4ee552b5221; + 0d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d + 1f + "" + "" + "" + 88af455e5264ee42; + 337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e + "" + 60 + "" + "" + 3349c44a62931118; + 57acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb95295 + "" + "" + 33 + 10 + 0084f273223d1321; + 966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030 + 370c33d090c54215 + abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb6 + 48e27fff63102758fe2b69ac26afa3349829b94586306fed + e506b433f4b8d79455ba85c9495a93fbdfd6d9b8905ff540 + 3a7eae4ca30b331e; + 54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df + 9fcbaca4 + 8b77dba189196d1ebba10b + 0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5 + 300fa70b6ef7bfd848bb6686af20bd3fdd3c24870e4b3e27ebe638a6574f74666b + 3c7cd92967f27b1b; + 306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f + 0eb5b647da6794 + c18b5337685a96ed65b9aca338527ef19b09c0 + 63c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1d + 5a4f347d4d422000d0df51f4cb24b0be321466d6730f7a811e36dc030c + 15585b78049dd4fe; + ad89d4b9b12012e4713df4 + "" + "" + "" + "" + fe363b1f2ccd1251; + 6795630e7952d22bb02d71 + 00 + "" + "" + "" + 9b93dde4b132c750; + b8b649377d20a8f083455b + "" + 66 + "" + "" + bbc2c3a8d6d3ee89; + 3e4ee1315f3c8f2aebfa92 + "" + "" + 14 + e6 + 66a62c95caa9cbfb; + 51dcd1af5813b70d30ce2f + 1fef6ef315d07983 + 91805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9 + cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308 + 2f5da54ea8b3beafd0f3dd6ac4e10650dd2ed421f8ce5ec1 + 9ce22826bbc14984; + be3c31e6bc58c0b7cadcb6 + 58b970e4 + 7479a684b5aefa69a4cd52 + 147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d + e1b7effaaf9fd5e129cfc598bc26a0100ea9bac25c51aeabb75a7127e05c1bc9bc + ae765f924e885d78; + 00f06dc188d472a784e0c6 + f21195a3b9f4ae + 985511265febd11c164720eef9eb1c8dd0b009 + 51f284649016ed00456331854bc78bf43966eb0cfa9138ddc399084456 + 6bc0e656e9939d5fe58ad77acbcec603f5111cbe660d6b62d1c241ba6c + 47b8a5c7cd546e34; + 08fe95e81c + "" + "" + "" + "" + 70b8e6f27adb97d9; + 2533e31c9c + 1a + "" + "" + "" + f334ea3a3b8ec059; + 9851bc2810 + "" + d8 + "" + "" + 802c25c30e3c0441; + 58cbbc8424 + "" + "" + d1 + 79 + 74d9b3cdc4ce7003; + 26b807e6da + a089c3f9099c5ffb + 824173d7634c04226f30cbb7f0e4a973a8cd190107314717 + a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b7 + f9e5d38f1d9ce21dc3b940af936de5b80b4ac4b034adb539 + 33d122be105fb43e; + 30374ffc9b + c597f56c + cbb2f294b38766fc69f6a9 + f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e3 + 9895b89d611def800949f45f4e61129a3722df9b15f37afca829d4fc08266acf57 + 7ac2cc22e1d5568d; + 2d65cc1770 + a18cbfe6effd1f + f6778554acf1270485b203a3c1c4c967c0a458 + cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b0 + bb5e83aa69b5356dceec0fe74656f2e4399e12c85e09dd2f8fb609c72a + 2b642aa6511caace; + 3cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b + "" + "" + "" + "" + 991808a4cd53e573; + 70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac84 + 51 + "" + "" + "" + 12bc329cc3ff10a9; + 399587011677508a15dde524af3e2bee0646541a42c2ec + "" + cc + "" + "" + 7ebd5d67b3fed4e4; + b44d65bad397abfaf529ee41cf9a05c7efedef3401539c + "" + "" + 51 + 1e + 6b6575eab9424e98; + d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a + 5718fd25014107c8 + e7d715a92add9589d1f5c054b2d983514605ec590294a319 + b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70 + 4c86b78d99617ef3a0e2ba3306379b71221b44b4f53f5526 + 7cb8282ea97b3894; + d17d4569eaff59a332ba58d5d5589bfe079753ee1a957e + b6d6699e + 6b7ea2725cb2dac07ecde9 + 5759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9 + 9001bbc3c0a5c6447968b8eec61f2e49ca7129b0560ea49201d997d682bc36984f + 0c14462ce512a43d; + cf44bbc8c6254d980398bd94e66eb4563d405e51881e99 + 027b8ab9aea3cc + f860b0009740763d96836c5f87b95460938de1 + 288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7 + 3bf9da6973a8dc56cebcb99962a74dc8638d11f4cb1d932162cd63136e + ff4072c9c5180f17; +} + +blowfish-ocb1 { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa906 + 0d2d4b6003062365 + "" + "" + "" + 5f3f51e08130263d; + b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d + 27a4ba234085406a + 61 + "" + "" + 8de51300e0d17d9d; + 36512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbd + a3b3e9878731ebfe + "" + dd + 11 + 1baa12d5cdfeeee5; + 4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa45072 + 7a9b542cde52ebfd + "" + a19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030 + c1901311bcbe5d48115af605ce28802572f30dff577e27ec + 330d726cadffef1c; + 370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306f + ed54154f8f28523c + 03d4de1600157846b710ee72807a2219bfb474fd71d891f2 + 4bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df + 0a2dd79bb802baad38fb7e60e979c30bbbbcae5e5bfe515d + 0ee0e2a8987f11b4; + 9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac + 8b0a22260c571b4a + "" + 42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c03 + 0f42a8f34bf068232057195d449b9414f3bb33a692bff50f90f86b2d83 + 6cfb2c8b4b3ac1f8; + 7ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3b + cd211499268878db + f30f1dad89d4b9b12012e4713df46795630e79 + 52d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa + eda7fb91f70e24d3ac9751e7132f6b104e41392dac28bf4f0e5daaa2b6 + 04f7c455e5d023ab; + 921451dcd1af5813b70d30 + ce2f1fef6ef315d0 + "" + "" + "" + 4a33cb478b8f393b; + 798391805da08da3aefc5f + 8584b7c5e617669c + 0f + "" + "" + 8745d6a0c38b7bb0; + 16e39815d4e9cfce3ed1ec + df3d264a7f16cb16 + "" + c2 + 3c + 20ab4fe539c6b1ef; + e815f422cdf0c8e30308be + 3c31e6bc58c0b7ca + "" + dcb658b970e47479a684b5aefa69a4cd52147ed12ca98698 + bc0a5d98e5825c5e804c67213a1d820e29ef7dfddab70a5f + 40854bd91c065d0d; + 1a874498ad0abef8bc4fcb + 70e27e98ef1f0446 + b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4 + ae985511265febd11c164720eef9eb1c8dd0b00951f28464 + 1a2ad5ef98fce431c6e9e85fdd057e59d2954f8e96bbadc8 + 979de99c867f2951; + 9016ed00456331854bc78b + f43966eb0cfa9138 + "" + ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d1 + 78687a94824bb12dfe6e650544f042524ead2780a8bb4dde09d3621ec4 + d8dd93d379eb140f; + 26b807e6daa089c3f9099c + 5ffb824173d7634c + 04226f30cbb7f0e4a973a8cd190107314717a7 + 7456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc5 + b58e5fed2f88013418795c660e6e4b5ae3262382a534d79656c02a42f1 + 7391763bfa5e91d1; + 97f56ccbb2 + f294b38766fc69f6 + "" + "" + "" + de47841b0e181038; + a9f2c0945f + fd505003cc0cae9c + e0 + "" + "" + 9e1855698acdf3f7; + 21a5f1fa4f + fa91544485f1a125 + "" + 8b + 46 + 279f95fd345d8d07; + 2b9b8f0911 + e32d65cc1770a18c + "" + bfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458 + 6abecbf72aed482a6f80d57b236c40d316e20362f5561ff6 + cc8e958357592f6f; + cb948bdd40 + 9b687fa3a6827b48 + 0aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e + 8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9 + 322b60b89783b356ffcddc812e11459c1841d1540a91057d + 48feb980547cfd06; + e9a79b1abf + 91b0851e5ca605ac + "" + 8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65 + 735b81e7bf11cb6e02de6657d638e735c41336f7d021d1e6b07c8aaa69 + f21aba6b029d81a5; + bad397abfa + f529ee41cf9a05c7 + efedef3401539c51d2a90bbf7f1bfc338ab0ef + 5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1 + 094621285cf10b55b5c7ac0287f2267a8b4f9fecdd2e4107a88c16bd91 + 0a2c24953366e55d; + f5c054b2d983514605ec590294a319b9802068a9f891bc + 5ba5afabf8c3122d + "" + "" + "" + c9a161d460c36f70; + 12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589b + fe079753ee1a957e + b6 + "" + "" + 60dd373e888b983a; + d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7ab + c8ad68daac90cfe2 + "" + 2d + 34 + f2b20b2e78622af4; + 2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d98 + 0398bd94e66eb456 + "" + 3d405e51881e99027b8ab9aea3ccf860b0009740763d9683 + 1d2773587c73b701d3cc8beb604ce8f285046e6879e5c0e5 + ba34965f7a472a8f; + 6c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e + 86041c1b9fc214e9 + ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c + 36800d9645563a308ba60076817523bd2abf1261b089d8f2 + b0d06d7557017e3cd08c88a3a3d744ec0d7d964e72197911 + 9de86854fdf00689; + 3a9c2835076a23faac2cdd67771cc667a8331f0a170b66 + 283e4f834a06148f + "" + 302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b3 + f91ee277a3c2b93ce6c8df23263fd829225d66ff7f8bba9612230e8bf1 + d2c7d587cbddcddd; + 3779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2 + b94b0820cab383a8 + cffeea7c486315799dc875fba578c8ec483789 + 8a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14 + 00e25b2c5fdee0b87cd2c66474f852256a4e3b6239ef6ba512af0f74c0 + 5711f23d4b34df7f; +} + +blowfish-pmac1 { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa906 + "" + db56f7585ef1b3ea; + 0d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d + 1f + fe51530be20f5059; + 337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e + 6057acc87638f508046733d9ff61cdbda3b3e9878731ebfe + 370a72ba02c69145; + dd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450 + 727a9b542cde52ebfda19d0ccc520f215eb57b + b31c99831d7ad455; + b3a4f3ebbbb18ac6c95a97 + "" + 41939f3db560fdb4; + a48030370c33d090c54215 + ab + d56476908d8efe7a; + d6b3ad54efc9a38378c5b9 + 3bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac + 7f864cbc1bee3343; + 26afa3349829b94586306f + ed54154f8f28523c03d4de1600157846b710ee + a344715c78dc0063; + 72807a2219 + "" + 78e276b95d095a71; + bfb474fd71 + d8 + 9b5c25004d486060; + 91f24bb65d + 1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbac + 1d4dbe26bc70c6bc; + a48b77dba1 + 89196d1ebba10b0467cb9fc2712a199e533fa9 + 3b97fb336799efbd; + 156308cdec3f768281e040a9b9a222bd689aef66f5306c + "" + cc20b90115cd712c; + eb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb + 0b + eb75059c3f5ccc65; + ad7d95214ade49cb3b6f5fe8368131115c037ba323fe1d + c8151784873f0eb5b647da6794c18b5337685a96ed65b9ac + f0576e12bc1af195; + a338527ef19b09c063c46f88de9fd41e72d7b97e23e6ea + bdff3bcd211499268878dbf30f1dad89d4b9b1 + e193575442a800ab; +} + +blowfish-ocb3 { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa906 + 0d2d4b600306 + "" + "" + "" + b3583d3de56211f4; + 2365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e + 6b0d27a4ba23 + 40 + "" + "" + 912c60b4f34b6731; + 85406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9 + ff61cdbda3b3 + "" + e9 + dd + 49ef753d0e5893dc; + 878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9 + b2fc5f + "" + a450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3 + 104cef2c140c06f2a9c502bd63c02be3d940a76e94b52e8e + 2279d2765293b605; + ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac + 26afa33498 + 29b94586306fed54154f8f28523c03d4de1600157846b710 + ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b + e2f8d8fe5551cca9b88351ee9e422ceb2ed4abfaca8fa2b8 + 4cce00e139bd21d6; + 571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a2 + 22bd689aef66 + "" + f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d + e4fddb14c2c34d5695f13bdc9e21f6ff4605c864e2e7b0550606d5f478 + c07b9776137a4225; + 95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c4 + 6f88de9fd41e + 72d7b97e23e6eabdff3bcd211499268878dbf3 + 0f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b64937 + c64055e9e272881679259cd8f6d67f2291cea67a6865f4af686f02f032 + 32eace6f457de00d; + 7d20a8f083455b663e4ee1 + 315f3c8f2aeb + "" + "" + "" + 99933637fa8f2b85; + fa921451dcd1af5813b70d + 30ce2f1fef6e + f3 + "" + "" + b6e8c9c6a45b2a56; + 15d0798391805da08da3ae + fc5f8584b7c5 + "" + e6 + 80 + 3facc6b40f6e5187; + 17669c0f16e39815d4e9cf + ce3ed1 + "" + ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6 + 859387df0c8d6efe243bba8c894f17fa1935f42cd6148235 + 4d1dd56b61f0988b; + bc58c0b7cadcb658b970e4 + 7479a684b5 + aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb + 70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784 + ebf8c0ff4e24b5754891cff817c499efa87b8a9fdf0d2cc1 + 1d3775fe8dc794e7; + e0c6f21195a3b9f4ae9855 + 11265febd11c + "" + 164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966 + cc19d5c325f9e65a669dc5e47d9ebfc15d3a3f609d8a96bf9d6eb710fa + dba9d363c65b7e0b; + eb0cfa9138ddc399084456 + 08fe95e81c25 + 33e31c9c1a9851bc2810d858cbbc8424d126b8 + 07e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd + 53fd73e769e423e95ea852b9f025096cff34e3d1902ff701cdf24790c8 + eb3ca419114e51fe; + 1901073147 + 17a77456f3ff + "" + "" + "" + be3a587aad834d02; + 669c732b58 + db8f48af65f7 + cc + "" + "" + 2d749c7591283c5c; + 9e3fb90e17 + 21b730374ffc + "" + 9b + 43 + 0e0346447f445eca; + c597f56ccb + b2f294 + "" + b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa + 06da8393393846121625c231930a8490f2a4ce8b89447e2b + 78e64ea8e4df5f24; + 4ffa915444 + 85f1a1258b + 2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1 + 270485b203a3c1c4c967c0a458cb948bdd409b687fa3a682 + 8f7152ef08106003140fd22ae1d7911123b04337f8e2cff6 + c3c1d8284b448b74; + 7b480aa3a4 + c84cef64f6c9 + "" + b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd20 + d0d64b53c566f1dc431a72dda89c51a7b7d25a57638af924b7f56d75e7 + c691e0e094254334; + 5b70e04c09 + 1d205cdad9e9 + a79b1abf91b0851e5ca605ac84513995870116 + 77508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529 + b930562d3cc00abaeaa1dc8ff5825cdf086e0ba72916c06d9bd4f837bd + 90343080f7fb1dda; + ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338a + b0ef5746ea8f + "" + "" + "" + 91f6852537252f8a; + dcccd213e33f7e8a5718fd25014107c8e7d715a92add95 + 89d1f5c054b2 + d9 + "" + "" + b36663b6367ef6ef; + 83514605ec590294a319b9802068a9f891bc5ba5afabf8 + c3122d12d7ff + "" + 3c + e5 + 1961c689d2d77714; + 41122d70d17d4569eaff59a332ba58d5d5589bfe079753 + ee1a95 + "" + 7eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7 + cb0853f95fc84b810db7f3b9518d6c1a1ef5e78a3d316746 + 5b65e59ea9a723f0; + abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb35 + 42a9cf44bb + c8c6254d980398bd94e66eb4563d405e51881e99027b8ab9 + aea3ccf860b0009740763d96836c5f87b95460938de1288c + fbd80f2a162c319b91c99ed4a0f8860cbad42c59792cf7ac + 35dac492225424a6; + 69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186 + ddf1f6a7a3aa + "" + 7e740da967828e3604b35b15ffaa6c36800d9645563a308ba600768175 + 75bef1ae59a3404b09299f06461e0cbb3a9d6e58d4f49928f9b0845f01 + f93d21e578e90e18; + 23bd2abf1261b089d8f23a9c2835076a23faac2cdd6777 + 1cc667a8331f + 0a170b66283e4f834a06148f302c3973accd56 + f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc + 6128d1bdba407d841d26fb849b2f1967f1877822a75c402b845bd5f1b1 + 2951dd60e7a50fe4; +} + +blowfish-ocb3-mct { + 56 1eaefdb48ac7e8be; + 52 b79553ab012d6259; + 48 e596561501cbb1d1; + 44 0b3d0dd4007cc8e1; + 40 5e01c4481579151f; + 36 f745536adb730368; + 32 261481ed1915729e; + 28 b6fa034db1ed80e8; + 24 0b7aed4db823ce0c; + 20 472a7cbbc3b93999; + 16 4434cb1c40f21097; + 12 4f64439b9bcedfc2; + 10 654a7c2699f7e4db; + 8 b0d1574724b61c02; + 56 883bad05122a; + 52 1cf7ba9a0e86; + 48 44d9c92bfb48; + 44 2ab05efeab38; + 40 fb1788302233; + 36 926b61ed2153; + 32 d240e2d8b6e9; + 28 6a7452bc8c50; + 24 7be498392971; + 20 90d3cb1c76c2; + 16 a4ce66e48d8f; + 12 15a879e95625; + 10 2af8e886f690; + 8 c3ecbf857159; + 56 f196b27c; + 52 84c6f8e6; + 48 2323c6f4; + 44 c3c03f9d; + 40 57979457; + 36 318c4335; + 32 1928bd41; + 28 cb2429ec; + 24 369cdefd; + 20 45e7c011; + 16 32768164; + 12 469cab17; + 10 17a3dd1d; + 8 a4a15a19; +} diff --git a/symm/t/cast128 b/symm/t/cast128 index a456ea09..7ea4b47d 100644 --- a/symm/t/cast128 +++ b/symm/t/cast128 @@ -13,3 +13,912 @@ cast128 { 0123456789abcdef 7ac816d16e9b302e; } + +cast128-cmac { + 60d7bcda163547d348b7551195 + "" + e027f02068e914e0; + e77022907dd1dff7dac5c9941d + 26 + a28361e0bd2c591c; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0 + 4eeb71793dd20683; + a54364c76c160f11896c479484 + 6ecfa14a7130c9f137120634c9519848a877ff + f46b0adba4856f4f; + 77bf79192a5b50 + "" + 79360635503a7f04; + ade5d9cd739a3d + 1f + 9a100ee7cd214433; + 337f29549e6b0d + 27a4ba234085406a6136512061f7080cc07df0591d8fa21f + 81e6063cc8dd3e25; + 2dd88374d8cde8 + e160ad10997a21635c6d62c9269029df3e6057 + 077ce3be2b167375; + acc87638f508046733d9 + "" + e0ac1c1c71776fcb; + ff61cdbda3b3e9878731 + eb + de618ec3a0d64ca2; + fedd4705e505da1435dc + eaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533 + 1b5ed15a16456292; + 966f27043eb621b7f65b + 000961040ef2f9b2fc5fa450727a9b542cde52 + fe228a47df7c250d; + ebfda19d0ccc520f21 + "" + e8d3cb82a354843c; + 5eb57bb3a4f3ebbbb1 + 8a + c7fcbad7ee9257d3; + c6c95a97a48030370c + 33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260 + 1d547d096465faf6; + 5faee2b03fb648e27f + ff63102758fe2b69ac26afa3349829b9458630 + 10bd2c18c3337a4f; +} + +cast128-ccm { + 60d7bcda163547d348b7551195 + e77022 + "" + "" + "" + 4905fdcf; + 907dd1dff7dac5c9941d26d0c6 + eb14ad + 56 + "" + "" + 327786b3; + 8f86edd1dc9268eeee533285a6 + ed810c + "" + 9b + 7d + 9d869519; + 689daaa9060d2d4b6003062365 + b0a54364c7 + 6c160f11896c4794846ecfa14a7130c9f137120634c95198 + 48a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e + c935111d2f5913c3a992e7b11d538a1f5750237258739dd7 + ccae7a45efc12caf; + 6b0d27a4ba234085406a613651 + 2061f7080c + c07df0591d8fa21f2dd88374d8cde8e160ad10 + 997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbd + 9bd2a0c0f027a5a1b56974b85be03dd3ffe81b5f2a2381170fb7eca747 + 711646ef1dde6cad; + a3b3e9878731eb + fedd47 + "" + "" + "" + af3e6347; + 05e505da1435dc + eaa7b1 + cc + "" + "" + 571ec017; + 49ae1d50c38201 + a89447 + "" + 6b + 1b + 1859fcd4; + 3f102b752eb952 + 9533966f27 + 043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542c + de52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a + 63f409a8d0dba1ec4c090efd260b557d0359482f69d62126 + 7d4b85fb7d13bf0c; + 97a48030370c33 + d090c54215 + abd6b3ad54efc9a38378c5b93bf4f2aad2605f + aee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed + 018425effd80fbb802f204bdefb41d4b2fa140dd2b2149580b72428bab + 53bd8b75c9a3bc09; + 54154f8f28523c03d4de + 160015 + "" + "" + "" + 4397bfc8; + 7846b710ee72807a2219 + bfb474 + fd + "" + "" + a28f8e1e; + 71d891f24bb65d156325 + 9f9eb5 + "" + 3b + cf + 185c4f64; + 571ea629c54d57dd2d42 + f70800df9f + cbaca48b77dba189196d1ebba10b0467cb9fc2712a199e53 + 3fa9156308cdec3f768281e040a9b9a222bd689aef66f530 + 030e417475032f357c1257444a95486a4e0e652beb78ee50 + a36e60d6e4fffa0d; + 6ceb0c6b08ac8b0a2226 + 0c571b4a42 + bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b + 6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b + ae6c8d1d32a0ecff25eb9c81ff41dc0f31a9e9df6d96d7aa499a001ad1 + cad9b682638f7a11; + 5337685a96ed65b9ac + a33852 + "" + "" + "" + cee2fb45; + 7ef19b09c063c46f88 + de9fd4 + 1e + "" + "" + f82a2ce3; + 72d7b97e23e6eabdff + 3bcd21 + "" + 14 + 8e + cf442fcb; + 99268878dbf30f1dad + 89d4b9b120 + 12e4713df46795630e7952d22bb02d7100b8b649377d20a8 + f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b7 + d3216e8ddc4bae39da814c7541496567ad7669f3ebfafba7 + ffef801deb5ef8fd; + 0d30ce2f1fef6ef315 + d079839180 + 5da08da3aefc5f8584b7c5e617669c0f16e398 + 15d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c + d9f3345b6b1782cd1db09c53d2076a2b84f4cc16e94c58cb46cbd5d85e + c46139beb639552b; +} + +cast128-eax { + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + de756459eefbe735; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + 706c2756289404eb; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + 1dba9d384981a899; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + 9c + e1c1cb285fe6fd42; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794 + 846ecfa14a7130c9f137120634c9519848a877ff77bf7919 + 2a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + 7ea32c98c18f380ebf49a8153a036aba80fc8219ee85ea9a + 678b76a28d6415ac; + 406a6136512061f7080cc07df0 + 591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c92690 + 29df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + 21ed0355fd3256ebee4847ec0d0f6a024e6ea0f2cd8a5de1f5bb139385 + d4a1d384f6234b97; + 05e505da1435dc + "" + "" + "" + "" + cbbb9ef570741e49; + eaa7b1cc49ae1d + 50 + "" + "" + "" + f8c34e199b130f87; + c38201a894476b + "" + 3f + "" + "" + 76bfe7342f08a0d9; + 102b752eb95295 + "" + "" + 33 + 40 + 78d8ced34fba2669; + 966f27043eb621 + b7f65b000961040e + f2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215e + b57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215 + 2ab0a37f0ebd0523111d8079b33285016f8038eb01d8c726 + 2557d7fde2b5cbf4; + abd6b3ad54efc9 + a38378c5b93bf4 + f2aad2605faee2b03fb648e27fff63102758fe + 2b69ac26afa3349829b94586306fed54154f8f28523c03d4de16001578 + cde7aba02b6c423e5a4c5bee6592a8c6beedd60b458982ecb96ec2d05a + 4b957468a1b84eaf; + 46b710ee72807a2219bf + "" + "" + "" + "" + 4c34faee63cc6ded; + b474fd71d891f24bb65d + 15 + "" + "" + "" + fe3d9bc8bb1fadc7; + 63259f9eb53b571ea629 + "" + c5 + "" + "" + 89349e8fa6362b16; + 4d57dd2d42f70800df9f + "" + "" + cb + f0 + 3f45042252ade21c; + aca48b77dba189196d1e + bba10b0467cb9fc2 + 712a199e533fa9156308cdec3f768281e040a9b9a222bd68 + 9aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb23 + b5c79faaecf9c2d65703aae2c578b606b455c25f6aec3a4b + fe3a14a18c793f8d; + 3bfa6a5cfb0bad7d9521 + 4ade49cb3b6f5f + e8368131115c037ba323fe1dc8151784873f0e + b5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88 + b8d413238c76153b01f0a2823e24414f91988638bf3a80cdb6a211700f + 12e4967ff0500b9f; + de9fd41e72d7b97e23 + "" + "" + "" + "" + caab65ebca9b09cd; + e6eabdff3bcd211499 + 26 + "" + "" + "" + 7fb3ef6dc33a52ea; + 8878dbf30f1dad89d4 + "" + b9 + "" + "" + 1781664543c4675f; + b12012e4713df46795 + "" + "" + 63 + 41 + 9d8c48bc137b207a; + 0e7952d22bb02d7100 + b8b649377d20a8f0 + 83455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d + 30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5 + bf81b5c1007332ff360b167545ff826c131e6279a40ec6f3 + e037dbce43a14ff2; + e617669c0f16e39815 + d4e9cfce3ed1ec + df3d264a7f16cb16c2e815f422cdf0c8e30308 + be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed1 + 9b3b606592501407cf47aa56b3136cca02d94d282ebf6d5f441b32b9f3 + d8a34c6cae422b2c; +} + +cast128-gcm { + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + 827e37433b2c1494; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + 603a0e329e3029ed; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + 09e36329c9190d21; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + 0b + 83b106e61ac95294; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794 + 846ecfa14a7130c9f137120634c9519848a877ff77bf7919 + 2a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + d83412ab72752e456aba4b235ea84e65d99a082caea1eba5 + 9ded1889068ab798; + 406a6136512061f7080cc07df0 + 591d8fa2 + 1f2dd88374d8cde8e160ad + 10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9 + b0f1bd0e10c71ddab6c3c3a1b5cb5e0cf831042e831b12789ac9d617e21e573dac + 8a619f19a69e0bff; + 878731ebfedd4705e505da1435 + dceaa7b1cc49ae + 1d50c38201a894476b3f102b752eb952953396 + 6f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52eb + fa5b4ee08950d597fcb0affdf0f0aa8174ca0e9dcfc4ee13e4b5a2bae1 + b6ce5f7d53e6177b; + fda19d0ccc520f + "" + "" + "" + "" + 522de0429e89383a; + 215eb57bb3a4f3 + eb + "" + "" + "" + 45fb1e234c4d8ccd; + bbb18ac6c95a97 + "" + a4 + "" + "" + 89dab6195164787c; + 8030370c33d090 + "" + "" + c5 + bd + 870b563762624fec; + 4215abd6b3ad54 + efc9a38378c5b93b + f4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26 + afa3349829b94586306fed54154f8f28523c03d4de160015 + 3cbe2ea8aa7c3ea77e46a9afbd7f69fc51f663820293720c + ff1dcf81a83ea960; + 7846b710ee7280 + 7a2219bf + b474fd71d891f24bb65d15 + 63259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebb + f54b9538cef3257defa694754b7e196a132d042c670e72a1dcb527f660b836f098 + 59f1ff473e5232e6; + a10b0467cb9fc2 + 712a199e533fa9 + 156308cdec3f768281e040a9b9a222bd689aef + 66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad + f8432f79ab5a3e07c7dff91e912d79f7e6b6828b8a10c74bf419d9448f + 0ec34f0d7a1b4c11; + 7d95214ade49cb3b6f5f + "" + "" + "" + "" + 08185a4aee37b676; + e8368131115c037ba323 + fe + "" + "" + "" + 14a6486a55038a65; + 1dc8151784873f0eb5b6 + "" + 47 + "" + "" + 598e10f99a3c9a58; + da6794c18b5337685a96 + "" + "" + ed + 39 + fd918834389b1469; + 65b9aca338527ef19b09 + c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89 + d4b9b12012e4713df46795630e7952d22bb02d7100b8b649 + 1c3d067c765e17b338cf91585a0caf2f70bc663db8274944 + 09ab5e3cd3740b16; + 377d20a8f083455b663e + 4ee1315f + 3c8f2aebfa921451dcd1af + 5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f + 4b8874ad4cb500f61ff68c73c68dda4f440ad538ded72c0d5a265ce5721cf354f9 + 77bda550c71cc140; + 16e39815d4e9cfce3ed1 + ecdf3d264a7f16 + cb16c2e815f422cdf0c8e30308be3c31e6bc58 + c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a87 + fba726477f0a66ba98a278b52e721b41ebb36556e59d2e9830e66fe0a1 + 9666883d3ef07a79; + 4498ad0abef8bc4fcb + "" + "" + "" + "" + 4417c135917f0b7e; + 70e27e98ef1f0446b4 + 2f + "" + "" + "" + 579b6455f429d389; + b144d44b6d00f06dc1 + "" + 88 + "" + "" + c0feccc75a38a7ea; + d472a784e0c6f21195 + "" + "" + a3 + ba + d3e312ae74483320; + b9f4ae985511265feb + d11c164720eef9eb + 1c8dd0b00951f284649016ed00456331854bc78bf43966eb + 0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc + ececbe9f36ef004be708cf21bf97615f62e9ef58803fe723 + 57ac52bfb40dd355; + 2810d858cbbc8424d1 + 26b807e6 + daa089c3f9099c5ffb8241 + 73d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db + 7dff8ee32fab541aa59bdccc84961db26644f6bd50773640afd3a22cd438f54026 + 916e18567fd17de8; + 8f48af65f7cc9e3fb9 + 0e1721b730374f + fc9bc597f56ccbb2f294b38766fc69f6a9f2c0 + 945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f09 + 3c6ea417e98fd5ed2874ef3b1d8b512fbbe5449541a8912afce6b85441 + 6c1dcdd2eef63a3e; +} + +cast128-ocb1 { + 60d7bcda163547d348b7551195 + e77022907dd1dff7 + "" + "" + "" + 35fcd5e38e3b51ae; + dac5c9941d26d0c6eb14ad568f + 86edd1dc9268eeee + 53 + "" + "" + 9750a7c045cb5fa6; + 3285a6ed810c9b689daaa9060d + 2d4b6003062365b0 + "" + a5 + 70 + 2007ad9ceaa910e8; + 4364c76c160f11896c4794846e + cfa14a7130c9f137 + "" + 120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d + 1d6fefbc39046f96c95a8e6a1b9dee24838ae0538c73cc2b + 367e4bd46fea6528; + 1f337f29549e6b0d27a4ba2340 + 85406a6136512061 + f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + 21635c6d62c9269029df3e6057acc87638f508046733d9ff + 0754a41170bb62612e1224d955d5c65fb33c4331487b17fc + bf7b46ca9365175f; + 61cdbda3b3e9878731ebfedd47 + 05e505da1435dcea + "" + a7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 491c578a12863680495817bbb1be6bb5cd068da6c097a4d7454c4e8da0 + d255ace5711af8ae; + 21b7f65b000961040ef2f9b2fc + 5fa450727a9b542c + de52ebfda19d0ccc520f215eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b9 + 97a20b90075f6b8cd05b2c101043d92167fd921a71668f63a3c1115b0f + 202da1820f237005; + 3bf4f2aad2605f + aee2b03fb648e27f + "" + "" + "" + 31e566cec6e241d7; + ff63102758fe2b + 69ac26afa3349829 + b9 + "" + "" + ca2c2e57da61fa0b; + 4586306fed5415 + 4f8f28523c03d4de + "" + 16 + 5d + 85b6fa491dfc6955; + 00157846b710ee + 72807a2219bfb474 + "" + fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d + 737de7976152fc336878cbbb9ede5469e5cc5d970933fd65 + 8f8227129780dd53; + 42f70800df9fcb + aca48b77dba18919 + 6d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f76 + 8281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22 + f2320eca3b003b64b91066ab2de93cdd408517d8a9728db9 + 538a1fa6a7597e50; + 260c571b4a42bb + 8fdb233bfa6a5cfb + "" + 0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc815178487 + 20c12e9ba584a56f7768fe92d9111a7eae80e149386c93d17f7904a41a + 48e10cd0a8be13c9; + 3f0eb5b647da67 + 94c18b5337685a96 + ed65b9aca338527ef19b09c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012 + 55e5fad364bb32f3fa056d496f84874281576e690d72fa33be655966e4 + a0b5a442a7297a49; + e4713df46795630e7952 + d22bb02d7100b8b6 + "" + "" + "" + 940a9694d41abe63; + 49377d20a8f083455b66 + 3e4ee1315f3c8f2a + eb + "" + "" + 7b6cad447bf0e593; + fa921451dcd1af5813b7 + 0d30ce2f1fef6ef3 + "" + 15 + 30 + 536c60f6f1d83c94; + d0798391805da08da3ae + fc5f8584b7c5e617 + "" + 669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e8 + 1c485850e9c9b37abb599a800973920b660fd62c31d374a4 + 3b5a7524db68ca3d; + 15f422cdf0c8e30308be + 3c31e6bc58c0b7ca + dcb658b970e47479a684b5aefa69a4cd52147ed12ca98698 + 1a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d4 + 097c9f86dc5ed84b2c4302fa4b10719337a1ee8feed7d101 + 8f642bc221b793b9; + 4b6d00f06dc188d472a7 + 84e0c6f21195a3b9 + "" + f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00 + 98a5dafa75c301e74727ecbba6a5047ed29491a660cef05ba70e74eaf4 + eb2ef400c45349a9; + 456331854bc78bf43966 + eb0cfa9138ddc399 + 08445608fe95e81c2533e31c9c1a9851bc2810 + d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f + b43644eaaa9f3060a3a2d0eb7b10f8829f2769eb4ceaed6b712550e71c + fb0381cb9425f488; + 30cbb7f0e4a973a8cd + 190107314717a774 + "" + "" + "" + a084a9815a7601a4; + 56f3ff669c732b58db + 8f48af65f7cc9e3f + b9 + "" + "" + 2ee2f881784c0227; + 0e1721b730374ffc9b + c597f56ccbb2f294 + "" + b3 + 05 + 683231980af7d491; + 8766fc69f6a9f2c094 + 5ffd505003cc0cae + "" + 9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65 + e4f05c8136721b99369335ba402941018889f1fe75f9cb76 + 88de859ee4e6c912; + cc1770a18cbfe6effd + 1ff6778554acf127 + 0485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b + 480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a + db871dcb9e6624a931cef6ffcbe61ebc77c8b60f19550476 + a74df4d69c389e3e; + 3e8128f8743d16687b + 7bb8deb9bd205b70 + "" + e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677 + 922755c3a636a359fcf8fbeda42c8de7d32d109c3d1e2bc6b7f7094e9b + f18c36d8b0f0d64b; + 508a15dde524af3e2b + ee0646541a42c2ec + ccb44d65bad397abfaf529ee41cf9a05c7efed + ef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a + c06849ccf2b34ffd7b497fd8936add1cb570227aa304c345092739d18b + 326e341574bedb1f; +} + +cast128-pmac1 { + 60d7bcda163547d348b7551195 + "" + 9908603f8e4ed537; + e77022907dd1dff7dac5c9941d + 26 + ab2e2df52a4ffd51; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0 + 3400ed5412e2c9f7; + a54364c76c160f11896c479484 + 6ecfa14a7130c9f137120634c9519848a877ff + 0f106ec05825e141; + 77bf79192a5b50 + "" + 536bca927005ffd1; + ade5d9cd739a3d + 1f + f69b33db8f802d6e; + 337f29549e6b0d + 27a4ba234085406a6136512061f7080cc07df0591d8fa21f + 0b99429b96428cb3; + 2dd88374d8cde8 + e160ad10997a21635c6d62c9269029df3e6057 + 0098d1d07d912367; + acc87638f508046733d9 + "" + da9779d1609cb9e1; + ff61cdbda3b3e9878731 + eb + 00096e5430e6e2bd; + fedd4705e505da1435dc + eaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533 + a91e29d999936af2; + 966f27043eb621b7f65b + 000961040ef2f9b2fc5fa450727a9b542cde52 + 1df06f8b2c0f4c39; + ebfda19d0ccc520f21 + "" + 78b9f4bb116ef26b; + 5eb57bb3a4f3ebbbb1 + 8a + 57afa587a9a123d5; + c6c95a97a48030370c + 33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260 + d32f3f141a62efe1; + 5faee2b03fb648e27f + ff63102758fe2b69ac26afa3349829b9458630 + cab1db46326dab8b; +} + +cast128-ocb3 { + 60d7bcda163547d348b7551195 + e77022907dd1 + "" + "" + "" + 80acf79035879e49; + dff7dac5c9941d26d0c6eb14ad + 568f86edd1dc + 92 + "" + "" + c1c0b7cf9333abd0; + 68eeee533285a6ed810c9b689d + aaa9060d2d4b + "" + 60 + b7 + 2ba34997b9b7c1e7; + 03062365b0a54364c76c160f11 + 896c47 + "" + 94846ecfa14a7130c9f137120634c9519848a877ff77bf79 + a50349e70f84c21e91ac4dae8e84334c4eded066c4906f46 + 044e9f72b51e120b; + 192a5b50ade5d9cd739a3d1f33 + 7f29549e6b + 0d27a4ba234085406a6136512061f7080cc07df0591d8fa2 + 1f2dd88374d8cde8e160ad10997a21635c6d62c9269029df + ff3c222bcd45bd08ed535a77e89023455b21fd6b198e5220 + 6078eab50bffcabf; + 3e6057acc87638f508046733d9 + ff61cdbda3b3 + "" + e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a89447 + c9cff5648431ab446232a4644f1c59af90abdc696868521a9632a765af + e993a7f8297d83bd; + 6b3f102b752eb9529533966f27 + 043eb621b7f6 + 5b000961040ef2f9b2fc5fa450727a9b542cde + 52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c + d94512471232da2099eee100523fb16bb45018f05f681f067aaf7af8d6 + 87dca8c2d5779501; + 33d090c54215ab + d6b3ad54efc9 + "" + "" + "" + da927642dafe6fd1; + a38378c5b93bf4 + f2aad2605fae + e2 + "" + "" + e890bed519c2bfc9; + b03fb648e27fff + 63102758fe2b + "" + 69 + f6 + a1e73f23ec2eddee; + ac26afa3349829 + b94586 + "" + 306fed54154f8f28523c03d4de1600157846b710ee72807a + 0cf707f93f9c389e7c78ef3e61d36d20604e1441b169fc9a + 6febc37ff410bc6f; + 2219bfb474fd71 + d891f24bb6 + 5d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcb + aca48b77dba189196d1ebba10b0467cb9fc2712a199e533f + 06e300b114e2b4bebe212cf694364bc44989b8cfe139b08a + b496b69d5f5f2406; + a9156308cdec3f + 768281e040a9 + "" + b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb23 + 0af7dab55d9223c86960d4b03e62b32f96a5c1ee581be399c93b15e789 + 97f72d7c401cf252; + 3bfa6a5cfb0bad + 7d95214ade49 + cb3b6f5fe8368131115c037ba323fe1dc81517 + 84873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c0 + a0f7f9f1e1934502280dfa21be7bd3eadab7541c17cccc03102dcb3454 + 22cc4588498bc2a5; + 63c46f88de9fd41e72d7 + b97e23e6eabd + "" + "" + "" + 869d689f3cb451ab; + ff3bcd211499268878db + f30f1dad89d4 + b9 + "" + "" + 10c4ca311ab0d4ea; + b12012e4713df4679563 + 0e7952d22bb0 + "" + 2d + ae + d91ecbfa408ed62c; + 7100b8b649377d20a8f0 + 83455b + "" + 663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f + 447474323cef334fa9a0733f9dcca98a6f5f79b395392cea + 9b75ce84a39e878e; + 1fef6ef315d079839180 + 5da08da3ae + fc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d + 264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0 + 4e006eb2b0cb5e16f592ac6c5601c80e7a97fb0725c1ca4f + adcac831efd97e58; + b7cadcb658b970e47479 + a684b5aefa69 + "" + a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446 + 9f8a879d391e2c63103be599717c39608d4f0d42ab0b17bb3515e1e210 + d2579224689f1c51; + b42fb144d44b6d00f06d + c188d472a784 + e0c6f21195a3b9f4ae985511265febd11c1647 + 20eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0c + 87e39284c048d9c1660e5437f1cc86615724448c5c86d185b1a54bc05c + 52b0cf04002f103f; + fa9138ddc399084456 + 08fe95e81c25 + "" + "" + "" + 08923b4787ecca64; + 33e31c9c1a9851bc28 + 10d858cbbc84 + 24 + "" + "" + 9c2d888635429e4f; + d126b807e6daa089c3 + f9099c5ffb82 + "" + 41 + 76 + 14aedb991bbdf5d5; + 73d7634c04226f30cb + b7f0e4 + "" + a973a8cd190107314717a77456f3ff669c732b58db8f48af + ec093b797db58fa9c9b88e58ffbde6f4f4c38fb6db25b117 + 3eeb6753ae39c984; + 65f7cc9e3fb90e1721 + b730374ffc + 9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003 + cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911 + 3ffec2f705cc006637248de55ef480c9401790a303ccd564 + 6d3b369a0699bf98; + e32d65cc1770a18cbf + e6effd1ff677 + "" + 8554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b + 91e2b0612406d31b88b044f838e29dc4bc08492a9d8b73b1751f6eb210 + d684fc47c7b172f0; + 480aa3a4c84cef64f6 + c9b53bf8f957 + f4b03cf43e89957f9a3e8128f8743d16687b7b + b8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac84 + f9bc629deb9e6dc3454415296389546e992975ef5c6dfba23357c06539 + d4d1265b9cad7cee; +} + +cast128-ocb3-mct { + 16 d2434caa22748e97; + 14 4dab36316a173b4c; + 12 25b37d39f09b8f7b; + 10 6ea2b818da01a012; + 8 e4e0aa59657d2246; + 6 29299e3845bdedad; + 4 99594416fa91c2f7; + 16 460ffc3b13c9; + 14 ff7bc7e6be51; + 12 e0a21b1ff4b7; + 10 5062cd9b7b51; + 8 5d40437352df; + 6 22a0f6279d79; + 4 429d09c799fc; + 16 a42ad529; + 14 9dec6cc9; + 12 15803553; + 10 5c50c831; + 8 4a2e5743; + 6 e10bbd1e; + 4 4a6bf7e7; +} diff --git a/symm/t/cast256.local b/symm/t/cast256.local new file mode 100644 index 00000000..a52ad886 --- /dev/null +++ b/symm/t/cast256.local @@ -0,0 +1,892 @@ +### Local tests for CAST256. + +cast256-cmac { + 60d7bcda163547d348b7551195 + "" + 550f6aa2b500f5b19d32c63502e8448b; + e77022907dd1dff7dac5c9941d + 26 + 198a435819e092069eaf3c5a455baf3c; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1371206 + 2e7ac3fd9be8475d5b81a6f5fd3392e9; + 34c9519848a877ff77bf79192a + 5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8 + 7bcad81a16a4c1d1cf5fc4f107d9e50c; + 8374d8cde8e160ad10997a21 + "" + 50fdac1d477bd12e61df27c230eb0858; + 635c6d62c9269029df3e6057 + ac + 8ac07980a2538da61bf9fdb8f9791197; + c87638f508046733d9ff61cd + bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 4e9a7999789a6d1041fd26295aaa4942; + 21b7f65b000961040ef2f9b2 + fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5 + ffbaaeeaf8f93c7c71c7708e21043c32; + 4215abd6b3ad54ef + "" + d3fc1c69dbbe8a358f5f968f8e60047e; + c9a38378c5b93bf4 + f2 + d37b1e960767df9d502e6c942e90f39d; + aad2605faee2b03f + b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219 + 55f8a2b6e7bd774ff32cac26cee4f1ef; + bfb474fd71d891f2 + 4bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9f + d33ece086863448e6714580ec9f8d267; + c2712a199e533fa9156308cdec3f768281 + "" + 9b818524f8ebef2f840938b85c30b9b8; + e040a9b9a222bd689aef66f5306ceb0c6b + 08 + 44a2b05a0953086b802e5dfbccef8691; + ac8b0a22260c571b4a42bb8fdb233bfa6a + 5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65 + ffa9d762bb11005e32a5747de41738c2; + b9aca338527ef19b09c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d + 4e21bb0835d28d84b50e6db35757d672; +} + +cast256-ccm { + 60d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9 + "" + "" + "" + aa9a4a79; + 941d26d0c6eb14ad568f86edd1 + dc9268eeee533285a6ed81 + 0c + "" + "" + c8a39dd0; + 9b689daaa9060d2d4b60030623 + 65b0a54364c76c160f1189 + "" + 6c + 2d + 73e78af5; + 4794846ecfa14a7130c9f13712 + 0634c9519848a877ff + 77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + af2bcbe02785e26888000200221db7ec8a96262bd4ac58f98de028ac5f0ab12ff4a6525254d7f78215727c2796d9de34 + d83e04bccd4cc28ee89db0528d559b4c; + 05e505da1435dceaa7b1cc49ae + 1d50c38201a894476b + 3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0c + cc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb6 + ae26d7c0fe93d7f36b4fe471099e64f0da7e0436df67adc9fbccbb9d12e26b9f086c3176ed28861c7d9afcfdb181dddb5b337c84b9 + 4eb8907ccd4025021d7117364de8c4f9; + 48e27fff63102758fe2b69ac + 26afa3349829b94586306f + "" + "" + "" + dcee39b3; + ed54154f8f28523c03d4de16 + 00157846b710ee72807a22 + 19 + "" + "" + d0f09e35; + bfb474fd71d891f24bb65d15 + 63259f9eb53b571ea629c5 + "" + 4d + b1 + 20282dc8; + 57dd2d42f70800df9fcbaca4 + 8b77dba189196d1ebb + a10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c57 + 1b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da67 + 9991d3ac6a6931127145d2ce4106eae3f0e588ed0e6a1c24d015d595640fe427ebb5753e1955ea8cfeca3dd0638b8e0b + a2dc9d2ee323e912007d462871314715; + 94c18b5337685a96ed65b9ac + a338527ef19b09c063 + c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e + 7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d079839180 + 1691f3064921baaa57137b92ce00739789fad53203a0c5c0683cad9da5e2a54c15b6ea69870a807b40fa2006fd631f790f43a88a86 + d5f6f01586bd510672cd9f062d846013; + 5da08da3aefc5f85 + 84b7c5e617669c0f16e398 + "" + "" + "" + 7104d66a; + 15d4e9cfce3ed1ec + df3d264a7f16cb16c2e815 + f4 + "" + "" + d82c0d6e; + 22cdf0c8e30308be + 3c31e6bc58c0b7cadcb658 + "" + b9 + a6 + cb4b7117; + 70e47479a684b5ae + fa69a4cd52147ed12c + a986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae98 + 5511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608 + 4763b77f7a624a9d1453034bea8d9c5061a93708adf6badc0e7372623212c427f6539c36f053398d051510adee65048f + 79884b4232ec8611c3e862865e3d60ec; + fe95e81c2533e31c + 9c1a9851bc2810d858 + cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a7 + 7456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0c + fdfefeef8313360ebe5d7c5448129278ab19acbb0625d7e0675ce22a334269067523466c1cbad10c0a8630ae2d94d3b9a38dfe3db0 + 2ba0749d5c88e7dde18a94a99bcc3b69; + ae9ce021a5f1fa4ffa91544485f1a1258b + 2b9b8f0911e32d65cc1770 + "" + "" + "" + be73551e; + a18cbfe6effd1ff6778554acf1270485b2 + 03a3c1c4c967c0a458cb94 + 8b + "" + "" + 922ec10b; + dd409b687fa3a6827b480aa3a4c84cef64 + f6c9b53bf8f957f4b03cf4 + "" + 3e + 9e + ceadc769; + 89957f9a3e8128f8743d16687b7bb8deb9 + bd205b70e04c091d20 + 5cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397 + abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107 + 882d1a8dcf897a5fd0b0a23aed8016eb4ba2290f47c51ffbb244fd10614dc98bdd072c8dd2607ccb0a8509c13141fc03 + 541f7a6fcf2c319c9bdf291490aabd96; + c8e7d715a92add9589d1f5c054b2d98351 + 4605ec590294a319b9 + 802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee + 1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44 + 87aacdd16e3d3bcd52d8bbbe6226bd5b405fd7ec9d93334a5ca599dfa600927a1270c54700d1d7ceb1fe25a033321359e98889bf74 + 9c7c6db5629007318783e4fadc1f1d67; +} + +cast256-eax { + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + 2b961641462baf0a23af6720a9197d0a; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + c27ec7e5c6e5b2c0722a835e433f5708; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + 91ee71af24a201bdc7dba1596261eced; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + 36 + 21caca7994e9579e303e7c24be9fdb7f; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794846ecfa14a7130c9 + f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7 + 080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61 + 242810649692db21e7595173fad46df3f55019d4e719ceb5bc09a733997fcacc846e6ec1e0589e4c9e5355dfaace122f + 4039884385c992be1a778520915dc0d6; + cdbda3b3e9878731ebfedd4705 + e505da1435dceaa7b1cc49ae1d50c3 + 8201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde + 52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260 + 6536f3d0bd3929eb609818c1cee5e2be47a1a02f0f883c34867f9966cfe97a31b2fd4c821c520e1be3d0a736dd1661b6190e24c1a6 + 33856bece05f1ca8fe19b530e407b966; + 5faee2b03fb648e27fff6310 + "" + "" + "" + "" + ee2162ee6e8410aa5200171d0c4024aa; + 2758fe2b69ac26afa3349829 + b9 + "" + "" + "" + 87a91471cda81dd33d9b42545c8b0b8c; + 4586306fed54154f8f28523c + "" + 03 + "" + "" + 0e5e8f75620078311d835458946c93ff; + d4de1600157846b710ee7280 + "" + "" + 7a + a6 + 18d59976b1087c9b1790cc5e6b29d3ff; + 2219bfb474fd71d891f24bb6 + 5d1563259f9eb53b571ea629c54d57dd + 2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222 + bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe836813111 + 303058fd583dbf8ab83aff89f31060650b03148c7330a6be6858eb1d384bac97798c4211f919b1170b2c1ce6d3d8b0da + 60ec12a7a132b714707aa1bfca3f3d67; + 5c037ba323fe1dc815178487 + 3f0eb5b647da6794c18b5337685a96 + ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89 + d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d + efd6f1f344975f001595f2d1e3254791c4f1054f4e0932a85a28c1296308bad1c38aa7c2b2be16f2b14b94de98ce44d0255979ed5f + 335688afe647757a98f871ebf99933b7; + 30ce2f1fef6ef315 + "" + "" + "" + "" + 57a1e64ab9765509b8abd4c36b616844; + d0798391805da08d + a3 + "" + "" + "" + 9b3d0bae4a9f3fc0cc4135d73b6471e7; + aefc5f8584b7c5e6 + "" + 17 + "" + "" + 7a3a4fd12ec71c3058d3edc4416d6e56; + 669c0f16e39815d4 + "" + "" + e9 + 31 + f15c15c0e14893b05d599ec77547c893; + cfce3ed1ecdf3d26 + 4a7f16cb16c2e815f422cdf0c8e30308 + be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98 + ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b009 + dab10d1acc2f9596d131f83d22dfcb5f76e3133ae715429bb9ae30c6c41b4035ea2ba2e6d2b7afd41ffb821b88b0f11b + 2b770827aad8b1bfdf838506622ea7d6; + 51f284649016ed00 + 456331854bc78bf43966eb0cfa9138 + ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb82 + 4173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc5 + 180b3ae40e896c401aa0ec3a9323a97b3063486d3016f504ba931948fe5f48455bee3defdcec5d43d2e5b96f021f45027bf304c4a7 + 36388109db5182725e7dc0c9e8c18e18; + 97f56ccbb2f294b38766fc69f6a9f2c094 + "" + "" + "" + "" + 65d71bd58e0cfc24609eb320f26c4144; + 5ffd505003cc0cae9ce021a5f1fa4ffa91 + 54 + "" + "" + "" + 5c3f108cadaeed7fdc40c74003074e4a; + 4485f1a1258b2b9b8f0911e32d65cc1770 + "" + a1 + "" + "" + deb0b205c88084de69e4dcd20f94372f; + 8cbfe6effd1ff6778554acf1270485b203 + "" + "" + a3 + 7d + e854cf62bc9c693207ab3c89432f5418; + c1c4c967c0a458cb948bdd409b687fa3a6 + 827b480aa3a4c84cef64f6c9b53bf8f9 + 57f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac + 8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef340153 + c8b37bf62703385c9441e1cdf357875ee437a15798e10c0717aefa605227bfffe401cfc610ae0b51d9f63e8098cc45bd + 4e68c56bb64b3d6ac08e35248a671884; + 9c51d2a90bbf7f1bfc338ab0ef5746ea8f + dcccd213e33f7e8a5718fd25014107 + c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7 + ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7ab + 3afadb7496af2b3d618391fb535d6c6b42cb20a259c0f2d359d83055062b3f3c8715fbe13fe3b001c254ded295b2225e461ce11d2c + 77dafdf4ffbffd0bafdc4b2a1c2a77f8; +} + +cast256-gcm { + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + e40bb3203b443cbb894937a4f69e6b67; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + e9c2fa823e33d9aac0cdff0f79008a96; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + c458bc5a2b89690b93e7d4603d8dc6c5; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + f3 + a32741ffd61b5bb53b79a7df1e2e849f; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794846ecfa14a7130c9 + f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7 + 080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61 + e8b2a245b1b44140bfde7f135603a3f4c088770181f486cee855087f0468fba9e4af3194c57ae401fd5304b6aca87204 + 7ba17b157ad26810dcc34b7a04b11a38; + cdbda3b3e9878731ebfedd4705 + e505da1435dceaa7b1cc49ae1d50c3 + 8201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde + 52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260 + e635fd965a15d413b93196514d7a577123025a4559f16734464afea880e538b0193db7477e52720ce3554332f406382cec81b57972 + c6fcab0d8311749afdfc54ff38f4484d; + 5faee2b03fb648e27fff6310 + "" + "" + "" + "" + 96bb8800b41ff193d4b4c65f59d19dde; + 2758fe2b69ac26afa3349829 + b9 + "" + "" + "" + 0318bc05a63c0e2dc859b0f13dad85ae; + 4586306fed54154f8f28523c + "" + 03 + "" + "" + 920fc4cab40ad51c11726fcb45c817ce; + d4de1600157846b710ee7280 + "" + "" + 7a + f6 + 947c572753bab643d56dd4095074acb1; + 2219bfb474fd71d891f24bb6 + 5d1563259f9eb53b571ea629c54d57dd + 2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222 + bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe836813111 + c663c80f1a24265a81261cf9ae9b38ea937ddc6a3662815341fb9677608d8a1ed64d70bea85fed028af8f56563d9a8c6 + 989401a20cf7eafc84c597493b6ad0a2; + 5c037ba323fe1dc815178487 + 3f0eb5b647da6794c18b5337685a96 + ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89 + d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d + fbc42f92cbccbe0dcc288a2781c8b0156a3ca42294cda5f5ba134558d63dfc445e57c58f5a262dba7c4fe923071a49006b0df6c76c + 27f0a0861ef2ce9d671123efa0f6bc26; + 30ce2f1fef6ef315 + "" + "" + "" + "" + 50e8f074272cc9a5a63212e7902d5df5; + d0798391805da08d + a3 + "" + "" + "" + 16203fda45ef8d1249caf3413f1718fc; + aefc5f8584b7c5e6 + "" + 17 + "" + "" + fe964dc3fd7220defc4b718b74e1bcfb; + 669c0f16e39815d4 + "" + "" + e9 + 8f + 07b2a554d209d7f24549dceb24015bf2; + cfce3ed1ecdf3d26 + 4a7f16cb16c2e815f422cdf0c8e30308 + be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98 + ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b009 + 1f97c51ad029f02dbebe7fd0faa41da5d523bf06055b9c13188549427c2b41f689be95c2a53dcd73a5497fbcd32b664d + 88fffe54f9bedb25fb5cd22f4d78b442; + 51f284649016ed00 + 456331854bc78bf43966eb0cfa9138 + ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb82 + 4173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc5 + 45170813ffb0c86e1d49c82c83b82d72ea126dbc788c27ec00b79ed4b266cbc66f9ef2311fb2c2464d1b81372dd120656250c427d0 + 736070378d728b22d9844d97bde5e22e; + 97f56ccbb2f294b38766fc69f6a9f2c094 + "" + "" + "" + "" + 7323880f89fb54d552c1a23505f238fb; + 5ffd505003cc0cae9ce021a5f1fa4ffa91 + 54 + "" + "" + "" + bbd60af0b8d37b6a322ab217d1d9cdc9; + 4485f1a1258b2b9b8f0911e32d65cc1770 + "" + a1 + "" + "" + 829cc05afc938051344df29091d390d6; + 8cbfe6effd1ff6778554acf1270485b203 + "" + "" + a3 + 5d + e3c0d0132c0bb48fe0424f4c72b763e8; + c1c4c967c0a458cb948bdd409b687fa3a6 + 827b480aa3a4c84cef64f6c9b53bf8f9 + 57f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac + 8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef340153 + 59516d118aa9a72775326beb658de1e0cfb0cda583731d1d69b0b47d0b0cd441844618383dca21b165b19a0c11dec493 + ae577e6433b84bef607dc9e0fcb9403a; + 9c51d2a90bbf7f1bfc338ab0ef5746ea8f + dcccd213e33f7e8a5718fd25014107 + c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7 + ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7ab + 992b8af618edee3cfc8554dff63c15cb2767f995be01271c2cfd8fd552ba9736e3b40674bd386359c6ad649bd6ec0259891bdfdfcd + b50c46ca1142d5d4c72930495fa48515; +} + +cast256-ocb1 { + 60d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9941d26d0c6 + "" + "" + "" + f4e4aa5505f37af61a5a972c9fddc162; + eb14ad568f86edd1dc9268eeee + 533285a6ed810c9b689daaa9060d2d4b + 60 + "" + "" + 584463e75d3ac1157672be951d0055a0; + 03062365b0a54364c76c160f11 + 896c4794846ecfa14a7130c9f1371206 + "" + 34 + 5c + b394bb4ab2b10e6e8cf2367e54a31532; + c9519848a877ff77bf79192a5b + 50ade5d9cd739a3d1f337f29549e6b0d + "" + 27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e + 5e5c6671bcd32b508fcdf1290a9270f30ac874189f9e647431527ad1e4ff12bd82060a376c2668bbaa4716e80bbc9884 + baeb21b394d13ec32b91057c7bf09405; + 6057acc87638f508046733d9ff + 61cdbda3b3e9878731ebfedd4705e505 + da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5f + a450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54 + 04f1f1082ac15c13cce9ec3c1fcbe8691ac8c736973073538f54a2cbc387064256e8add5a710c2102f0230773d54e1a7 + 6e9c01e8e1cb63e1e545a84f84280577; + efc9a38378c5b93bf4f2aad260 + 5faee2b03fb648e27fff63102758fe2b + "" + 69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9e + ffd476af7d1a5f68a96ecdfb466048936ba4d8c91e81057b23305c0d3120a0f30bfa23abcb7d3497912ceb161471933582a715b3ab + 1d3aa8cb71b538852d3e674e5bf3615d; + b53b571ea629c54d57dd2d42f7 + 0800df9fcbaca48b77dba189196d1ebb + a10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b + 0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da67 + 4d82601ad1a7e07573bed65ed8da86942029c74dc50df0e0f80b00bf3745f4266652f1e017340a07e94f96333f3333d61d0d940e5a + 34184bf2c44520892ed7e493d2af584a; + 94c18b5337685a96ed65b9ac + a338527ef19b09c063c46f88de9fd41e + "" + "" + "" + 09b578e0b6e9577963d2995dcd8f0bd5; + 72d7b97e23e6eabdff3bcd21 + 1499268878dbf30f1dad89d4b9b12012 + e4 + "" + "" + 80b1ce3d1a2d08a260dcffd4a9f16abf; + 713df46795630e7952d22bb0 + 2d7100b8b649377d20a8f083455b663e + "" + 4e + ce + afd445d169a181a0d3ab494c21e853e0; + e1315f3c8f2aebfa921451dc + d1af5813b70d30ce2f1fef6ef315d079 + "" + 8391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e303 + 4e1f0bbef82b78b779df16313c391c02bd6f7345ce682a14b23b2abb89a2096e54a1de1109e918c370716ebdc875b2d4 + dffb8a8a04a9255086211180d478d1b7; + 08be3c31e6bc58c0b7cadcb6 + 58b970e47479a684b5aefa69a4cd5214 + 7ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9 + f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908 + 499f455e969ad8bc52698430481a1c43a6cb786edb33fcde2407be7a18c6477d35d59eee05c523f870918e68500b78cd + 0d448fdf7f32a1b4ea521a182677dd36; + 445608fe95e81c2533e31c9c + 1a9851bc2810d858cbbc8424d126b807 + "" + e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3f + 5d96f90a43251e531c7932bb2bd9b281f8281589ba1c490ddf3c57a32516eba4bd0eb418af024566da98156a0f83def4b51b2bb90f + 43fecf4cb095b89844141707fd0d2643; + b90e1721b730374ffc9bc597 + f56ccbb2f294b38766fc69f6a9f2c094 + 5ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6 + 778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f + ca44fbee713e258d9aea6a41b419530669e861a4c0beadc5653841d50680ab7fed4ad201ed83833d26e8afa66b8a91173eae53bc59 + 82a696e7b8a54d2cbdceedfae2d7182b; + 9a3e8128f8743d16 + 687b7bb8deb9bd205b70e04c091d205c + "" + "" + "" + d92ad5b9acbcf8fb954dbb262344b172; + dad9e9a79b1abf91 + b0851e5ca605ac845139958701167750 + 8a + "" + "" + e5e0cdba48ea323b69c3fd7873c61ac8; + 15dde524af3e2bee + 0646541a42c2ecccb44d65bad397abfa + "" + f5 + 29 + 989ebeaeb57f545955d5c2b8a76a5457; + 29ee41cf9a05c7ef + edef3401539c51d2a90bbf7f1bfc338a + "" + b0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b980 + f5017b00265a7b059589fe8549cd0d622805099dcf5d466a35dff3c0acbf40c1116ca692ec2388ec1fdbffdbfcc727f1 + e00724826deae7efecaff58c6ff8dc4f; + 2068a9f891bc5ba5 + afabf8c3122d12d7ff3c41122d70d17d + 4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68 + daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9 + 38e8e939b456444e7a6dd8dd56c53376dfa8896e37a9cd10b16c5a5a2daa0ee885a2d3df7925fe71b8ad09d35e722a8c + 81f8c645830a84009214a06300fc2feb; + aea3ccf860b00097 + 40763d96836c5f87b95460938de1288c + "" + 69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308b + a7e718049be63223f6fcf229b7f907650bf6e10e8f53425f395df8b8aedf0658b001e1b1e717e75ba1b3750c9fa03714dbc5efeffa + e9fb84545896f7a672652dab4176b86b; + a60076817523bd2a + bf1261b089d8f23a9c2835076a23faac + 2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa + 8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578 + e8f501b22016ada9cbfef68407a289863b7d3880603c3da8ea796352253441971cdd0171e8b57dcb32c58a078d439d523f36e17889 + 2b2a2e481234b511a0fee70c0924f67c; + c8ec4837898a92142b5b0677da1ac27311 + 7b45bcfff5d5f8b6fde2893232a9f81d + "" + "" + "" + c1cab79fe94cbf28ab64b07b34396c84; + 14517ffae475f6b94a43a67b3d380d2f9a + aafe2dd721c0095c8808847689211450 + ba + "" + "" + 743df0e8509186cfb6ce313315f591df; + 8095ffab1eaadf66fd22ac1976063e113a + b61f813e28a1397a7974a1d7f4220c78 + "" + 5f + 26 + 503f2efabf0d67ef1e3ad58f79d6f17d; + e426a5a0e80f678d404147842941feeffd + c2eb44dc8c0d5e8f444f7f4e0c893959 + "" + b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3 + 1e06a0e13fc9f0db0a30711b19af2ec7eaa3927ec5338711ceb30b6610c76e473b7a3668ece81dc0f73253a516413982 + 53954399118d5578d98e208d426b0366; + ab6cf8556b7aa776945948d1b8834df219 + 6c92ec1718dcdeee0d52d9539726d281 + 0391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa + 4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0 + a4d6895902d47c9ef748ad8517e2d12561e2c068f16250af0fed5f2e2ae5afbd7f207ba0511039c9ae5562d230a2fac4 + 1ead7569ca82cb5cfd6b06fe6956c91e; + a9aabb6c4e3c3554f8fb1ef61614c27029 + 5dfc0ca6551ca4bdb75359f91cb9d921 + "" + 056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3d + 0a97b9588a0aff4d72af4e22c74f318a40355d94e0e0b200a0f8d06d5bd9d54728665f613e0bba43618f384303c3332e7bb746ec9c + 99bb95cd33b76350d1b7de4543001f0e; + f6c2b3fac7cbcf96523d4723f91801325e + b8553236651c96788d73d192ee53b3f3 + ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f64b837 + bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b5 + a3a36df6117ba70650188e6b240237f97b545f08ad010f9eff2cc0a7ced297c38c495ac0f293cd4a6d9f56d96e31b17f64c7bcf949 + 6bab5e7330a0c1f6a651f0a33e17327f; +} + +cast256-pmac1 { + 60d7bcda163547d348b7551195 + "" + e8bbe6976040b637c5730cead91a9243; + e77022907dd1dff7dac5c9941d + 26 + afcd96681e4a0ed5af47bb8b17d41497; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1371206 + b584d84fe844382627cede2f7c6e5299; + 34c9519848a877ff77bf79192a + 5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8 + b232cc4c44afe1700f942c996e05e589; + 8374d8cde8e160ad10997a21 + "" + f0389f03e4cfb0f88b4016b8a96703bb; + 635c6d62c9269029df3e6057 + ac + 754f863997eb465cc5ada5e2febd22a7; + c87638f508046733d9ff61cd + bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 407841bdebb8eb02d282ef5890f76dbf; + 21b7f65b000961040ef2f9b2 + fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5 + 0ee25678e76d4bfd0bd892417f3a4aeb; + 4215abd6b3ad54ef + "" + d31ba003e87b06c6f0eb3c9e93090855; + c9a38378c5b93bf4 + f2 + cd4ec1c2080823a36b6a223b15c6f9db; + aad2605faee2b03f + b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219 + 8c621081c3ad80573f0003d5ed7b7ca8; + bfb474fd71d891f2 + 4bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9f + a61047ab500558a62e494702a55f0426; + c2712a199e533fa9156308cdec3f768281 + "" + d7db14580abbffd94087bd893c44bb9c; + e040a9b9a222bd689aef66f5306ceb0c6b + 08 + f30bab211ce253887d48d7788411a8fd; + ac8b0a22260c571b4a42bb8fdb233bfa6a + 5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65 + e7cb4245e3ce926311a964eaff43f853; + b9aca338527ef19b09c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d + 37e48b490fc5476f6a317210987af58c; +} + +cast256-ocb3 { + 60d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9941d26 + "" + "" + "" + 5d4fdb3278da8699e7a297755690b588; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9 + 06 + "" + "" + fd23cef36d5d13dfbbc3f91a2edcbed2; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794846ecfa14a71 + "" + 30 + c1 + 5890dc2ce6ae75f9c7072f3c06cc6aac; + c9f137120634c9519848a877ff + 77bf79192a5b50ade5d9cd + "" + 739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + ba75fc237e106f6352333d944d8a6a0f8bfe641cf9242e343a63b4d591c2cdc18a6c50c88580b23e045876e62431d6d1 + e9af104923e66478d2bbac836c025af7; + 21635c6d62c9269029df3e6057 + acc87638f508046733d9ff61cd + bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 21b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a480 + 856379775dd26a3b347f1e25434238aabccfbd70ecabff489dafd8d2d25fe86ae4cf09bd85f2c739f0365c4e7afb4bee + a43529bee26dd2393a369de5d2e23a55; + 30370c33d090c54215abd6b3ad + 54efc9a38378c5b93bf4f2aad260 + "" + 5faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219 + 60e28a1e146d789fa2b63320cfd0dbb8de71aad2d5f2df5200a8c179db39e2a64e8f7bc0926ac95fc11a65cbd36935bc03c8b13dca + 3666a5ec5c24466c0680e3d6062b30fd; + bfb474fd71d891f24bb65d1563 + 259f9eb53b571ea629c54d57dd2d + 42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040 + a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c + 513e8a344d74844ef67effb6805688174ea7685fd8ba3a2860cd98864c5bcc699b69fe97963dcfbcda987b28e4d649ca5d45378a13 + 6259e08c9387922cf33a2e5b86c23e38; + 037ba323fe1dc8151784873f + 0eb5b647da6794c18b5337685a96 + "" + "" + "" + cfafee3e2ee7315fefeac9f823d4ec1e; + ed65b9aca338527ef19b09c0 + 63c46f88de9fd41e72d7b97e23e6 + ea + "" + "" + 8fd186584d18210cb316f19fea0bd516; + bdff3bcd211499268878dbf3 + 0f1dad89d4b9b12012e4713df467 + "" + 95 + 33 + d846c750ec238730ef2611b41ef1d22f; + 630e7952d22bb02d7100b8b6 + 49377d20a8f083455b663e + "" + 4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f + 66e0593cdc31156b9cca5bbce514957973bd0186966333560fbc521e413fb7b3ce7189751f51708bf4424cca548a00b0 + e4f02aebcee994443b0f438fd0d5e917; + 16e39815d4e9cfce3ed1ecdf + 3d264a7f16cb16c2e815f422cd + f0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4f + cb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb + d182ac26587fc4ea051ef5e86830194d4f6afe030b7a72355dfc307eefffb85fc972a9e0ec73e25db66d4e98d8d7eb9d + 3905dfc881ebf47d63219f7a3824c03c; + 1c8dd0b00951f284649016ed + 00456331854bc78bf43966eb0cfa + "" + 9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f + fac401c9710f7a1adf621eef0169fd85bb9efd3e5a2a59f2d985c72665c3fe1043563eee9bcfe24902ea2a20565ee073c556c0897d + ea51bd57dadb6f1b4aa5b85471a9b725; + 30cbb7f0e4a973a8cd190107 + 314717a77456f3ff669c732b58db + 8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0c + ae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a4 + 7f34458b9f7bdb1075bd95a6577649bc50bbfedeedb3eaadad5610c87416621c2496fb61c94ad5ac6d1d157556260ed4ee9762c5df + 4e98bd96daadb7ba8885c55080fd944f; + 58cb948bdd409b68 + 7fa3a6827b480aa3a4c84cef64f6 + "" + "" + "" + 54a6dca9e4f6b456ca9a72d5430bf37f; + c9b53bf8f957f4b0 + 3cf43e89957f9a3e8128f8743d16 + 68 + "" + "" + 680d5049038160aeee6c7a4a3030990d; + 7b7bb8deb9bd205b + 70e04c091d205cdad9e9a79b1abf + "" + 91 + c0 + 3cf99a9f061f858ef7e0fb11d7f16467; + b0851e5ca605ac84 + 51399587011677508a15dd + "" + e524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0 + f364b814e500ef9ab50b1f0c5cc2bddd2c00e7622f85716506453739fbb85ebd7c9c5d6bb06e1ac7974b640bab4fb2e2 + 538fef69d96b24725f40d036b7b6664e; + ef5746ea8fdcccd2 + 13e33f7e8a5718fd25014107c8 + e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70 + d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8 + 4f968a35e00430a894fa0af39d8e46cbf5f6df56646d148532800533bc976923e4d9228a11def3ff976c6be7ccead573 + 9722d670c7a13c44d3fb8e0e97446166; + ad68daac90cfe22d + 2f1f2968cc42fa8b669ed3bb3542 + "" + a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69 + 237f19a52651cdcd603091b3ca1b5d7a3131761987c0f38664d0432917123bbee65ccaa962fdee1431aa26d2f247e05df2017a6f73 + 002e125c7224c549106c0c0f82d731ed; + d80ea12ff4bb5f06 + 9b8a2e86041c1b9fc214e9ca2186 + ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089 + d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4 + 2094d61a83dedbd274dee89488d255879775fff59a5dcd4c270e2adab6e0d4ed7b48e867cd45400d77a667104d6a35a0056b5b9abe + dce0b2e1f5ba9e73aaff6246e384cbfe; + fa8fec816ac861a8b33779f09e7a10fc02 + a8f48afa3080ee119a52a9a817e4 + "" + "" + "" + 6dea6ebbce273e40bf6b5ba1481560d5; + f2b94b0820cab383a8cffeea7c48631579 + 9dc875fba578c8ec4837898a9214 + 2b + "" + "" + ef480ec30616d41fb86f4f79858304ca; + 5b0677da1ac273117b45bcfff5d5f8b6fd + e2893232a9f81d14517ffae475f6 + "" + b9 + 77 + 8af99e141e67210c5239e5d4f6016e59; + 4a43a67b3d380d2f9aaafe2dd721c0095c + 8808847689211450ba8095 + "" + ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feef + b0315e2ce88fdc82212d14ff369becee4cc30d1e591bc73e9cb807b5014e50d2a03b416ccf7e403d0c788000d752c544 + 565bb827571e2d4746ea15001c3a511c; + fdc2eb44dc8c0d5e8f444f7f4e0c893959 + b74dc23a7bb40e7e0013e51506 + 86d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf8556b7aa776945948d1b8 + 834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e73 + 6882d9145b766d004aa23db26e6727b910a52b3524cf41e5b079063a5690876e00b8446bd49b8fe0f96c646a9de22fd0 + e1478799571f8ad2f2376901b4d0f0ba; + 7882cd09c2b9a80f34c0fde11c2481b11f + c76bfa4dbf710a9e544e0c536ca1 + "" + e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270 + 9bfd938b0ddf7d005d20bab1060d8fae70cf3b084df0d31b76aeb0356f191bd9dd16f2a0ac6a6b4c910a7bb5982dc5ff5b7e99bf3a + 3fbd1c0a5b88616249b56c90758cdb29; + 295dfc0ca6551ca4bdb75359f91cb9d921 + 056b7de74fc9a9b37154ce6c0b39 + 6179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fa + c7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b5 + a58bb37e7d47cb624edd3d81393569f1b6dfe1cc7e50af93187a22abdef670f81e2ec2e0ddbc5a4fce6f61bfd15e642128305d6026 + 95512397bf2fdd2cb6111fd1763fe66b; +} + +cast256-ocb3-mct { + 32 620ecceaf099c7d1772580169dbe93a0; + 28 95fc3dcdf6e2582e821ad38cd6c26391; + 24 acef03ad345af5000cb5ef196bd366b7; + 20 0f1a6f49f6853abb75ce4e90c58599ea; + 16 4258d565f5ec42869802cd5cd5d21a96; + 12 f8fc10048890fb153d71d846be4ce8ed; + 10 aaab0bbcaa81d7b3b5b1269a3761335e; + 8 329c9f836301b423469a56ad770da468; + 4 68fc11ed2e38d35ba5bf89af2c9f856c; + 32 c0310249248a38ff9950a833; + 28 b97c775bf1d0c8ef8284fee6; + 24 67a579e69bf507321be80304; + 20 7077b0ec786e90698b31f028; + 16 f326d6be1d1c2758e6bc69b1; + 12 8f3110db5963f2e800f22f06; + 10 58a1c2500f16812836519b52; + 8 3d0e35b1e0cb21f08410d22f; + 4 6d9f16f675839f35d0a9bf7d; + 32 af8a0e5cd2075f9c; + 28 9610c921db423fd5; + 24 e228f80e94e1fe31; + 20 a7a0f74679eb7543; + 16 b64ea6aa7a4d2c86; + 12 695dda9261b41e4f; + 10 27064d4c545536b5; + 8 1868f259d6049ec2; + 4 fc3fd6f530c8c94e; +} diff --git a/symm/t/chacha b/symm/t/chacha index 4777803a..f7b19a63 100644 --- a/symm/t/chacha +++ b/symm/t/chacha @@ -31,12 +31,19 @@ chacha8-core { xchacha20 { ## Unfortunately, XChaCha isn't actually defined anywhere, even though it's - ## obvious how to do it. These test vectors are from - ## https://github.com/DaGenix/rust-crypto/blob/master/src/chacha20.rs + ## obvious how to do it. + ## These test vectors are from + ## https://github.com/DaGenix/rust-crypto/blob/master/src/chacha20.rs 1b27556473e985d462cd51197a9a46c76009549eac6474f206c4ee0844f68389 69696ee955b62b73cd62bda875fc73d68219e0036b7a0b37 "" 0 "" 4febf2fe4b359c508dc5e8b5980c88e38946d8f18f313465c862a08782648248018dacdcb904178853a46dca3a0eaaee747cba97434eaffad58fea8222047e0de6c3a6775106e0331ad714d2f27a55641340a1f1dd9f94532e68cb241cbdd150970d14e05c5b173193fb14f51c41f393835bf7f416a7e0bba81ffb8b13af0e21691d7ecec93b75e6e4183a; + + ## This one's from draft-irtf-cfrg-xchacha-03. + 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f + 404142434445464748494a4b4c4d4e4f5051525354555658 "" 64 + 5468652064686f6c65202870726f6e6f756e6365642022646f6c65222920697320616c736f206b6e6f776e2061732074686520417369617469632077696c6420646f672c2072656420646f672c20616e642077686973746c696e6720646f672e2049742069732061626f7574207468652073697a65206f662061204765726d616e20736865706865726420627574206c6f6f6b73206d6f7265206c696b652061206c6f6e672d6c656767656420666f782e205468697320686967686c7920656c757369766520616e6420736b696c6c6564206a756d70657220697320636c6173736966696564207769746820776f6c7665732c20636f796f7465732c206a61636b616c732c20616e6420666f78657320696e20746865207461786f6e6f6d69632066616d696c792043616e696461652e + 7d0a2e6b7f7c65a236542630294e063b7ab9b555a5d5149aa21e4ae1e4fbce87ecc8e08a8b5e350abe622b2ffa617b202cfad72032a3037e76ffdcdc4376ee053a190d7e46ca1de04144850381b9cb29f051915386b8a710b8ac4d027b8b050f7cba5854e028d564e453b8a968824173fc16488b8970cac828f11ae53cabd20112f87107df24ee6183d2274fe4c8b1485534ef2c5fbc1ec24bfc3663efaa08bc047d29d25043532db8391a8a3d776bf4372a6955827ccb0cdd4af403a7ce4c63d595c75a43e045f0cce1f29c8b93bd65afc5974922f214a40b7c402cdb91ae73c0b63615cdad0480680f16515a7ace9d39236464328a37743ffc28f4ddb324f4d0f5bbdc270c65b1749a6efff1fbaa09536175ccd29fb9e6057b307320d316838a9c71f70b5b5907a66f7ea49aadc409; } chacha8 { @@ -226,3 +233,21 @@ chacha20 { 000000000000000000000002 "" 0 "" 965e3bc6f9ec7ed9560808f4d229f94b137ff275ca9b3fcbdd59deaad23310ae; } + +chacha20-poly1305 { + ## Test from RFC7539. + 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f + 070000004041424344454647 + 50515253c0c1c2c3c4c5c6c7 + 4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e + d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116 + 1ae10b594f09e26a7e902ecbd0600691; + + ## Test from draft-irtf-cfrg-xchacha-03. + 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f + 404142434445464748494a4b4c4d4e4f5051525354555657 + 50515253c0c1c2c3c4c5c6c7 + 4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e + bd6d179d3e83d43b9576579493c0e939572a1700252bfaccbed2902c21396cbb731c7f1b0b4aa6440bf3a82f4eda7e39ae64c6708c54c216cb96b72e1213b4522f8c9ba40db5d945b11b69b982c1bb9e3f3fac2bc369488f76b2383565d3fff921f9664c97637da9768812f615c68b13b52e + c0875924c1c7987947deafd8780acf49; +} diff --git a/symm/t/des b/symm/t/des index 7b753045..8b3edb29 100644 --- a/symm/t/des +++ b/symm/t/des @@ -60,3 +60,465 @@ des { 0e329232ea6d0d73 8787878787878787 0000000000000000; } + +des-cmac { + bef260d7bcda1635 + "" + 38adff25bb9e255b; + 47d348b7551195e7 + 70 + a70403c9dc15813e; + 22907dd1dff7dac5 + c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed + 5e05047524a92169; + 810c9b689daaa906 + 0d2d4b6003062365b0a54364c76c160f11896c + d345f04671d2f856; + 4794846ecfa14a + "" + d1f159eb76e2dcb3; + 7130c9f1371206 + 34 + 1728ecf20653375b; + c9519848a877ff + 77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4 + 6f19d2ec30d3057a; + ba234085406a61 + 36512061f7080cc07df0591d8fa21f2dd88374 + 2b5a2cec413de519; +} + +des-ccm { + bef260d7bcda1635 + 47d348 + "" + "" + "" + 97684266; + b7551195e7702290 + 7dd1df + f7 + "" + "" + 46cb911b; + dac5c9941d26d0c6 + eb14ad + "" + 56 + da + 952bf9f2; + 8f86edd1dc9268ee + ee533285a6 + ed810c9b689daaa9060d2d4b6003062365b0a54364c76c16 + 0f11896c4794846ecfa14a7130c9f137120634c9519848a8 + cfdc3c0afd5fdd440f0e1898cb7cc518539e54d77a406117 + 2c49a88b22b8108b; + 77ff77bf79192a5b + 50ade5d9cd + 739a3d1f337f29549e6b0d27a4ba234085406a + 6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + fcd66aee455ff8c114978554c7a9debc11b642cff67c13f54f43c84302 + 7c38973da8da2aec; + 21635c6d62c926 + 9029df + "" + "" + "" + ce0d4ebc; + 3e6057acc87638 + f50804 + 67 + "" + "" + 3e4ba751; + 33d9ff61cdbda3 + b3e987 + "" + 87 + 41 + 2a565655; + 31ebfedd4705e5 + 05da1435dc + eaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533 + 966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a + e1eaaf9f5e53008063e0e21e064025aa423fb9a0a86996d0 + e257ab7ac4bc8b67; + 9b542cde52ebfd + a19d0ccc52 + 0f215eb57bb3a4f3ebbbb18ac6c95a97a48030 + 370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2 + 52f8b409665916709096ea1116886f51d56d6f48f3e0c298f8ded5d660 + 5d9404a726617d55; +} + +des-eax { + bef260d7bcda1635 + "" + "" + "" + "" + 4fd7b7ceb605971d; + 47d348b7551195e7 + 70 + "" + "" + "" + 362aa5d62008f0b2; + 22907dd1dff7dac5 + "" + c9 + "" + "" + da21b21da7d57854; + 941d26d0c6eb14ad + "" + "" + 56 + 01 + 91d13047c75395e9; + 8f86edd1dc9268ee + ee533285a6ed810c + 9b689daaa9060d2d4b6003062365b0a54364c76c160f1189 + 6c4794846ecfa14a7130c9f137120634c9519848a877ff77 + ff6584338c84f608f20f9b45387b79f759e4bbffdb97a914 + a58397ff608476d2; + bf79192a5b50ade5 + d9cd739a3d1f33 + 7f29549e6b0d27a4ba234085406a6136512061 + f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62 + af4d58477434a67a527bd0abfbed0edc0e1d65db63ce387eee315f026a + e566a58b1afd6dde; + c9269029df3e60 + "" + "" + "" + "" + ce840f6919760b2f; + 57acc87638f508 + 04 + "" + "" + "" + d2004b1898772d24; + 6733d9ff61cdbd + "" + a3 + "" + "" + 7280bac984631a8b; + b3e9878731ebfe + "" + "" + dd + e8 + 75dd11b7cf5f0dae; + 4705e505da1435 + dceaa7b1cc49ae1d + 50c38201a894476b3f102b752eb9529533966f27043eb621 + b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfd + 5cdd7720adf593db701494fc78e1bbd48e8fb79727cf09ad + b5c7ced07cae4060; + a19d0ccc520f21 + 5eb57bb3a4f3eb + bbb18ac6c95a97a48030370c33d090c54215ab + d6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff6310 + df23153076ea552eabc472d40d9c4e859e707cb2acc2d8aa7e828b949b + 01fcd2f2e30d870c; +} + +des-gcm { + bef260d7bcda1635 + "" + "" + "" + "" + b95298cbf804f0df; + 47d348b7551195e7 + 70 + "" + "" + "" + 22c33c13d4284fda; + 22907dd1dff7dac5 + "" + c9 + "" + "" + 32e3e11e770712c8; + 941d26d0c6eb14ad + "" + "" + 56 + fa + 366c7284d32c1c2b; + 8f86edd1dc9268ee + ee533285a6ed810c + 9b689daaa9060d2d4b6003062365b0a54364c76c160f1189 + 6c4794846ecfa14a7130c9f137120634c9519848a877ff77 + 44f226038a81c0bf29f563401555ce1f15c8d35934f4757e + 19590fc8720cd177; + bf79192a5b50ade5 + d9cd739a + 3d1f337f29549e6b0d27a4 + ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10 + 4cf8117a588a98676db9fcbc8fd592fc8e065354683bdde62cbdaec0ba89ef9a7e + 0ddf3556750fe18e; + 997a21635c6d62c9 + 269029df3e6057 + acc87638f508046733d9ff61cdbda3b3e98787 + 31ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f10 + bd611ed6e68f3bb8ae3b8b3eccae4a26c64ee9febe4fd46797bf634545 + 5233b3b52edfd9b3; + 2b752eb9529533 + "" + "" + "" + "" + deb6bb8d0f98e479; + 966f27043eb621 + b7 + "" + "" + "" + f72d871e2f82a356; + f65b000961040e + "" + f2 + "" + "" + 12e8da9a09fd309b; + f9b2fc5fa45072 + "" + "" + 7a + 06 + 51a7355bf0814b08; + 9b542cde52ebfd + a19d0ccc520f215e + b57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215 + abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb6 + 4826d7b427e8d7dbfd700e8ef337210c86c2d5994781ebb0 + 19ab2b84d1b8165a; + 48e27fff631027 + 58fe2b69 + ac26afa3349829b9458630 + 6fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f2 + 43672e659b8698b44928111f7554e23e567bec8fd062387337d29a6f8332f563e3 + c3ef31f3b831d4e9; + 4bb65d1563259f + 9eb53b571ea629 + c54d57dd2d42f70800df9fcbaca48b77dba189 + 196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040 + c34cf61443b0c83d4120ed5e4ffd2469382732dfb776bc2ce6771cfaf6 + 346dc157ce8660d5; +} + +des-ocb1 { + bef260d7bcda1635 + 47d348b7551195e7 + "" + "" + "" + 1e777d9a35a9e879; + 7022907dd1dff7da + c5c9941d26d0c6eb + 14 + "" + "" + 90dff887c781b59b; + ad568f86edd1dc92 + 68eeee533285a6ed + "" + 81 + 55 + 5c9be7f28d9f3021; + 0c9b689daaa9060d + 2d4b6003062365b0 + "" + a54364c76c160f11896c4794846ecfa14a7130c9f1371206 + 98fabe1568fd4a31b60b6b90cc58dee9852314abdf9f4d89 + 32bf6f1f094d55d1; + 34c9519848a877ff + 77bf79192a5b50ad + e5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136 + 512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad + ec6d227abc440c6ece3ba42013676031c0fb2960d0d65985 + 485047e83b3b11af; + 10997a21635c6d62 + c9269029df3e6057 + "" + acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da14 + 1b7100307ae4b3ca2e3f973e2ccd11be6245f9b081a36cc023801d9a8f + 5e2e02663e595bc7; + 35dceaa7b1cc49ae + 1d50c38201a89447 + 6b3f102b752eb9529533966f27043eb621b7f6 + 5b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f21 + 23ba63682d64c1e2ed3c14de44c492cf82ac3c63b1e85ae1d5905c1577 + a2786c37e5b03355; + 5eb57bb3a4f3eb + bbb18ac6c95a97a4 + "" + "" + "" + 846708610518ffc4; + 8030370c33d090 + c54215abd6b3ad54 + ef + "" + "" + 152246d59c398d68; + c9a38378c5b93b + f4f2aad2605faee2 + "" + b0 + 79 + d74b0529249254f2; + 3fb648e27fff63 + 102758fe2b69ac26 + "" + afa3349829b94586306fed54154f8f28523c03d4de160015 + 90d6861b964eed693b629e01188d4e50fcd236e71ccdc734 + 0611bd11e7649655; + 7846b710ee7280 + 7a2219bfb474fd71 + d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f7 + 0800df9fcbaca48b77dba189196d1ebba10b0467cb9fc271 + 9fb915d584569a6bc699706d225c9f131bed57d39b7bb4e3 + fdc4da4d6d428967; + 2a199e533fa915 + 6308cdec3f768281 + "" + e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb + 78e88cc7c809ee0d77e4550e3ba943fa3390b0e035bb4569fff7bc58ce + 821ba4f7ffd7cc02; + 8fdb233bfa6a5c + fb0bad7d95214ade + 49cb3b6f5fe8368131115c037ba323fe1dc815 + 1784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09 + e6b1c822199a5821020dea58a059635e7ceaa997c3bf8338bade196e39 + 417dceee9a662328; +} + +des-pmac1 { + bef260d7bcda1635 + "" + 87398f9b84eacbd3; + 47d348b7551195e7 + 70 + c4a6d220ebf7ce9e; + 22907dd1dff7dac5 + c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed + 9847df50037cb1ba; + 810c9b689daaa906 + 0d2d4b6003062365b0a54364c76c160f11896c + fe45499fb92b19ae; + 4794846ecfa14a + "" + c7fc008258249c34; + 7130c9f1371206 + 34 + 5d742a297938a8a1; + c9519848a877ff + 77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4 + 7cfba1467a3d156a; + ba234085406a61 + 36512061f7080cc07df0591d8fa21f2dd88374 + 0b547da65d93cc08; +} + +des-ocb3 { + bef260d7bcda1635 + 47d348b75511 + "" + "" + "" + 4b59c22684f05b82; + 95e77022907dd1df + f7dac5c9941d + 26 + "" + "" + 4cd9eea7a5f450a6; + d0c6eb14ad568f86 + edd1dc9268ee + "" + ee + d2 + c2fd51cbecc7d7da; + 533285a6ed810c9b + 689daa + "" + a9060d2d4b6003062365b0a54364c76c160f11896c479484 + 5618b880cf7e0455afe09f1aa07e38de2eee04ffbba014a5 + a22ffdfcd123b06f; + 6ecfa14a7130c9f1 + 37120634c9 + 519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29 + 549e6b0d27a4ba234085406a6136512061f7080cc07df059 + 7198f4d67f9d7ccae66e114745dd13b874d837fde0b5260a + e35c2d0fc8291130; + 1d8fa21f2dd88374 + d8cde8e160ad + "" + 10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cd + a71a247ba8ca953a41dabaabf6c2c6a88f5e83c466a18fd8fd7b7595b8 + f00ab9e066d2b84b; + bda3b3e9878731eb + fedd4705e505 + da1435dceaa7b1cc49ae1d50c38201a894476b + 3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5f + ac3adc8ac7c662d73901110404b26e56622c2b0208a34517256ca0876b + a5bd20d0748afcc7; + a450727a9b542c + de52ebfda19d + "" + "" + "" + 0fe8c6e02dfc921b; + 0ccc520f215eb5 + 7bb3a4f3ebbb + b1 + "" + "" + 70f6e10b0765c5e5; + 8ac6c95a97a480 + 30370c33d090 + "" + c5 + fc + e4a4438e74e98df5; + 4215abd6b3ad54 + efc9a3 + "" + 8378c5b93bf4f2aad2605faee2b03fb648e27fff63102758 + 659653c7ad91a79469d940fa2363013b939286f21cc49eee + f15e30c3bfe7697d; + fe2b69ac26afa3 + 349829b945 + 86306fed54154f8f28523c03d4de1600157846b710ee7280 + 7a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea6 + ce4e983f478dbf2b09b3bad8af3dd6341645b8d4b492ff68 + d1179f9268c3b779; + 29c54d57dd2d42 + f70800df9fcb + "" + aca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cd + d337d3fd33b17c42b364dc862e8b85f506e4f444ed7f63ed4440b65bf8 + 898fa93ba1e83b92; + ec3f768281e040 + a9b9a222bd68 + 9aef66f5306ceb0c6b08ac8b0a22260c571b4a + 42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c03 + 139b42f78a74486d2488d4de046e14b0b8d9c49efc78718b87d5f72697 + 8e529f719d87d2ee; +} + +des-ocb3-mct { + 8 d3d27b14989225a9; + 7 eb3be38e3517c6d1; + 8 70d5d3c75417; + 7 93e83240fae6; + 8 bdc8b8e1; + 7 4407c007; +} diff --git a/symm/t/des3 b/symm/t/des3 index f1adb1a6..afe7398a 100644 --- a/symm/t/des3 +++ b/symm/t/des3 @@ -39,3 +39,938 @@ des3 { 0123456789abcdeffedcba987654321089abcdef01234567 0123456789abcde7 de0b7c06ae5e0ed5; } + +des3-cmac { + ## Examples from NIST. + + 0123456789abcdef23456789abcdef01 + "" + 79ce52a7f786a960; + 0123456789abcdef23456789abcdef01 + 6bc1bee22e409f96e93d7e117393172a + cc18a0b79af2413b; + 0123456789abcdef23456789abcdef01 + 6bc1bee22e409f96e93d7e117393172aae2d8a57 + c06d377ecd101969; + 0123456789abcdef23456789abcdef01 + 6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51 + 9cd33580f9b64dfb; + + 0123456789abcdef23456789abcdef01456789abcdef0123 + "" + 7db0d37df936c550; + 0123456789abcdef23456789abcdef01456789abcdef0123 + 6bc1bee22e409f96e93d7e117393172a + 30239cf1f52e6609; + 0123456789abcdef23456789abcdef01456789abcdef0123 + 6bc1bee22e409f96e93d7e117393172aae2d8a57 + 6c9f3ee4923f6be2; + 0123456789abcdef23456789abcdef01456789abcdef0123 + 6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51 + 99429bd0bf7904e5; + + ## Locally generated tests. + 60d7bcda163547d348b7551195e7 + "" + 97b9dfb874462432; + 7022907dd1dff7dac5c9941d26d0 + c6 + f403026117612b0e; + eb14ad568f86edd1dc9268eeee53 + 3285a6ed810c9b689daaa9060d2d4b6003062365b0a54364 + 4e0fbacfa297003b; + c76c160f11896c4794846ecfa14a + 7130c9f137120634c9519848a877ff77bf7919 + 19d5f833e07e2015; + 2a5b50ade5d9cd73 + "" + ed38c0855386e014; + 9a3d1f337f29549e + 6b + c86e5386ee0e7b04; + 0d27a4ba23408540 + 6a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8 + d5306ab188df59b5; + e160ad10997a2163 + 5c6d62c9269029df3e6057acc87638f5080467 + b6fc8dee2287152c; + 33d9ff61cdbda3b3e9878731ebfedd47 + "" + 349cd58ebc44cb39; + 05e505da1435dceaa7b1cc49ae1d50c3 + 82 + a8322086e22dbed8; + 01a894476b3f102b752eb9529533966f + 27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b54 + 35c70f6e2cbab396; + 2cde52ebfda19d0ccc520f215eb57bb3 + a4f3ebbbb18ac6c95a97a48030370c33d090c5 + 639e5e64b410da07; + 4215abd6b3ad54efc9a38378c5b93bf4f2aad2605f + "" + 41240c9c71435050; + aee2b03fb648e27fff63102758fe2b69ac26afa334 + 98 + ab4c2c83747e8c5b; + 29b94586306fed54154f8f28523c03d4de16001578 + 46b710ee72807a2219bfb474fd71d891f24bb65d1563259f + eff715a559241957; + 9eb53b571ea629c54d57dd2d42f70800df9fcbaca4 + 8b77dba189196d1ebba10b0467cb9fc2712a19 + 2753a7135b48898f; +} + +des3-ccm { + 60d7bcda163547d348b7551195e7 + 702290 + "" + "" + "" + aa48bfd6; + 7dd1dff7dac5c9941d26d0c6eb14 + ad568f + 86 + "" + "" + 06de8798; + edd1dc9268eeee533285a6ed810c + 9b689d + "" + aa + 67 + 35d148d9; + a9060d2d4b6003062365b0a54364 + c76c160f11 + 896c4794846ecfa14a7130c9f137120634c9519848a877ff + 77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4 + a0cbf7ade835afc80d0244a41b72699e7f135479dcbf06f7 + 9d8fd60bbb5deed9; + ba234085406a6136512061f7080c + c07df0591d + 8fa21f2dd88374d8cde8e160ad10997a21635c + 6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e98787 + 09be940770a72970058ad3f06c973a2b58a7cc912892bc397eff73662e + 9146a93e7398cddb; + 31ebfedd4705e505 + da1435 + "" + "" + "" + 92740192; + dceaa7b1cc49ae1d + 50c382 + 01 + "" + "" + d1803413; + a894476b3f102b75 + 2eb952 + "" + 95 + 63 + c416162e; + 33966f27043eb621 + b7f65b0009 + 61040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc52 + 0f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090 + b70fe9f3c530c75595207f22867614779980e9ada1c35be5 + 236101f21d127547; + c54215abd6b3ad54 + efc9a38378 + c5b93bf4f2aad2605faee2b03fb648e27fff63 + 102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de + ffc2c6c900f35a8d4c0bc244cf5ebff8f9999f4ce5759b39131585d376 + 9661947e6ea6d306; + 1600157846b710ee72807a2219bfb474 + fd71d8 + "" + "" + "" + 1afd62e9; + 91f24bb65d1563259f9eb53b571ea629 + c54d57 + dd + "" + "" + 9be5f1b8; + 2d42f70800df9fcbaca48b77dba18919 + 6d1ebb + "" + a1 + 2f + 8ec7e387; + 0b0467cb9fc2712a199e533fa9156308 + cdec3f7682 + 81e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a2226 + 0c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b + 479741dd816d10d912b027aa913872636fc029c5b3b5e786 + b52afd4780869038; + 6f5fe8368131115c037ba323fe1dc815 + 1784873f0e + b5b647da6794c18b5337685a96ed65b9aca338 + 527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd21149926 + 2659d885994c1c74498d5caa2a19430c3622f508c1754794f736759134 + 1fd64bfce60b9b7c; + 8878dbf30f1dad89d4b9b12012e4713df46795630e + 7952d2 + "" + "" + "" + cbf3fe95; + 2bb02d7100b8b649377d20a8f083455b663e4ee131 + 5f3c8f + 2a + "" + "" + 622e5637; + ebfa921451dcd1af5813b70d30ce2f1fef6ef315d0 + 798391 + "" + 80 + 71 + 1a8cd2c7; + 5da08da3aefc5f8584b7c5e617669c0f16e39815d4 + e9cfce3ed1 + ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6 + bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147e + 820f2b98a0887f75cabdd9085299ba9d20e0c02e0e997019 + 4b2b92958f792723; + d12ca986981a874498ad0abef8bc4fcb70e27e98ef + 1f0446b42f + b144d44b6d00f06dc188d472a784e0c6f21195 + a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016 + 04baa89b0f016a9eb9f9f555b539e33fde914515ab13f2506927f4a0db + 266553d3216d3444; +} + +des3-eax { + 60d7bcda163547d348b7551195e7 + "" + "" + "" + "" + fb8989aca27d4e49; + 7022907dd1dff7dac5c9941d26d0 + c6 + "" + "" + "" + d6928baa49d00fad; + eb14ad568f86edd1dc9268eeee53 + "" + 32 + "" + "" + 33a565f808e5486a; + 85a6ed810c9b689daaa9060d2d4b + "" + "" + 60 + 79 + a70d6c7cd5e64642; + 03062365b0a54364c76c160f1189 + 6c4794846ecfa14a + 7130c9f137120634c9519848a877ff77bf79192a5b50ade5 + d9cd739a3d1f337f29549e6b0d27a4ba234085406a613651 + 9df7de45b395c138ed3f1c47399d41e00bad9d29625f6cbb + ffe26f440f8c69d8; + 2061f7080cc07df0591d8fa21f2d + d88374d8cde8e1 + 60ad10997a21635c6d62c9269029df3e6057ac + c87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435 + 698d38628b4297877182f76af79b7a17fafba3580f403a1c0645416006 + 056a29aa5eec7e3b; + dceaa7b1cc49ae1d + "" + "" + "" + "" + cca6200e06749307; + 50c38201a894476b + 3f + "" + "" + "" + 71f50318e1a16b5d; + 102b752eb9529533 + "" + 96 + "" + "" + b553cae3d6e4ccb5; + 6f27043eb621b7f6 + "" + "" + 5b + eb + 6f6d185a5644e5dc; + 000961040ef2f9b2 + fc5fa450727a9b54 + 2cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c9 + 5a97a48030370c33d090c54215abd6b3ad54efc9a38378c5 + 02f9df6832af2567bb074a96ff52ff9ef27cb6df55ed6912 + 6919ed7c6d0c9686; + b93bf4f2aad2605f + aee2b03fb648e2 + 7fff63102758fe2b69ac26afa3349829b94586 + 306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474 + 332681d1ab4ad4e8eee4f4b578efee58c917514f4d3c8ca33f50281a53 + 863ec2f3f702fa3a; + fd71d891f24bb65d1563259f9eb53b57 + "" + "" + "" + "" + 80199187ffd10cea; + 1ea629c54d57dd2d42f70800df9fcbac + a4 + "" + "" + "" + 54afba7a1543f424; + 8b77dba189196d1ebba10b0467cb9fc2 + "" + 71 + "" + "" + 9cb93469265f4d14; + 2a199e533fa9156308cdec3f768281e0 + "" + "" + 40 + 80 + e97aceb64f2af2bb; + a9b9a222bd689aef66f5306ceb0c6b08 + ac8b0a22260c571b + 4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8 + 368131115c037ba323fe1dc8151784873f0eb5b647da6794 + e9d68e86a6b48c7d9c78122bda02edc1b1419cb3031c60e4 + 57fcc7556b89f2a9; + c18b5337685a96ed65b9aca338527ef1 + 9b09c063c46f88 + de9fd41e72d7b97e23e6eabdff3bcd21149926 + 8878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100 + f89817786143348d71bd1ee8d1016e7256a94589b86a3ce582d7a9a374 + 0add4b3bd1159ff5; + b8b649377d20a8f083455b663e4ee1315f3c8f2aeb + "" + "" + "" + "" + f7c8ae1e42180c1a; + fa921451dcd1af5813b70d30ce2f1fef6ef315d079 + 83 + "" + "" + "" + b1dce877e070e318; + 91805da08da3aefc5f8584b7c5e617669c0f16e398 + "" + 15 + "" + "" + e373707f027e7557; + d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cd + "" + "" + f0 + ef + b49b83dc48872748; + c8e30308be3c31e6bc58c0b7cadcb658b970e47479 + a684b5aefa69a4cd + 52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef + 1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195 + 81e03369c6ecf1d8fb8c84a9817e0481b6de9ab9312737a4 + f9ad8a3df2d97500; + a3b9f4ae985511265febd11c164720eef9eb1c8dd0 + b00951f2846490 + 16ed00456331854bc78bf43966eb0cfa9138dd + c39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126 + d05f8c73aa124cdfe56cd74db66498169f829858ed7ad4366d6388f6ae + 1a54e1c0b2765dd8; +} + +des3-gcm { + 60d7bcda163547d348b7551195e7 + "" + "" + "" + "" + 132e46ca9dbab9db; + 7022907dd1dff7dac5c9941d26d0 + c6 + "" + "" + "" + bfd51a7057175d5e; + eb14ad568f86edd1dc9268eeee53 + "" + 32 + "" + "" + d86615981ba738da; + 85a6ed810c9b689daaa9060d2d4b + "" + "" + 60 + 58 + ed191f4620eaf05c; + 03062365b0a54364c76c160f1189 + 6c4794846ecfa14a + 7130c9f137120634c9519848a877ff77bf79192a5b50ade5 + d9cd739a3d1f337f29549e6b0d27a4ba234085406a613651 + aa3017ec2824335d1d4ced7dfa26a12168b7f1666fc0c262 + 5f991803dc1e6270; + 2061f7080cc07df0591d8fa21f2d + d88374d8 + cde8e160ad10997a21635c + 6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd + 9c0ed71aaf781676ef39d8f8e1fc9688f0bb74b4b13346ef27c096114375191d99 + 1af29d5d8d54dd86; + 4705e505da1435dceaa7b1cc49ae + 1d50c38201a894 + 476b3f102b752eb9529533966f27043eb621b7 + f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f + 70bd822a653d5d478b5b833cba2e8317b4bc5cc0f3b63481cad478b43c + db44ad57ba2d5450; + 215eb57bb3a4f3eb + "" + "" + "" + "" + 1e48437f8a8d8ed9; + bbb18ac6c95a97a4 + 80 + "" + "" + "" + a5cbaee18d95f020; + 30370c33d090c542 + "" + 15 + "" + "" + 2d353887e03a32a7; + abd6b3ad54efc9a3 + "" + "" + 83 + 95 + 7e18fe4cf4d6debd; + 78c5b93bf4f2aad2 + 605faee2b03fb648 + e27fff63102758fe2b69ac26afa3349829b94586306fed54 + 154f8f28523c03d4de1600157846b710ee72807a2219bfb4 + 4db1999e265acd8766761cb5b48a3d7bf61e264daf209900 + c498552a4665b7a1; + 74fd71d891f24bb6 + 5d156325 + 9f9eb53b571ea629c54d57 + dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533f + edcab4a157a12abde9e4743bd4d9351b0b6fe8c3b304c6daf3455197471e1eabdf + baf50f2e628a8632; + a9156308cdec3f76 + 8281e040a9b9a2 + 22bd689aef66f5306ceb0c6b08ac8b0a22260c + 571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131 + 31865bdd67531355562674e18401ba3e453fc36b8390c5ef81802616fb + a837fdccf1d1647e; + 115c037ba323fe1dc8151784873f0eb5 + "" + "" + "" + "" + b81a0ef79153b70a; + b647da6794c18b5337685a96ed65b9ac + a3 + "" + "" + "" + a519f2296fa3debe; + 38527ef19b09c063c46f88de9fd41e72 + "" + d7 + "" + "" + 5ec4b107491149c1; + b97e23e6eabdff3bcd211499268878db + "" + "" + f3 + 30 + 0824b10396c7f8ba; + 0f1dad89d4b9b12012e4713df4679563 + 0e7952d22bb02d71 + 00b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa92 + 1451dcd1af5813b70d30ce2f1fef6ef315d0798391805da0 + 0237988024ea8379f5a851a1a1df21241c0f794ef45c528b + 0bc36677cc8cad46; + 8da3aefc5f8584b7c5e617669c0f16e3 + 9815d4e9 + cfce3ed1ecdf3d264a7f16 + cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5 + 0a501f6458635eb8074e565be165b71b922c8907caaa5bc385bb62a4f2711a70a5 + d51e68d40adb01c0; + aefa69a4cd52147ed12ca986981a8744 + 98ad0abef8bc4f + cb70e27e98ef1f0446b42fb144d44b6d00f06d + c188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb + 7af7a90baa5a4ec5904454bd0d62a3beafc988913073eb04f3748af96a + 20721ecf26d54b13; + 1c8dd0b00951f284649016ed00456331854bc78bf4 + "" + "" + "" + "" + ac407ef838e78ff3; + 3966eb0cfa9138ddc39908445608fe95e81c2533e3 + 1c + "" + "" + "" + de0e93debf2119fd; + 9c1a9851bc2810d858cbbc8424d126b807e6daa089 + "" + c3 + "" + "" + 292a3b10a3279110; + f9099c5ffb824173d7634c04226f30cbb7f0e4a973 + "" + "" + a8 + 68 + a0021d91c51fbdb5; + cd190107314717a77456f3ff669c732b58db8f48af + 65f7cc9e3fb90e17 + 21b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0 + 945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a125 + e47c416a265254284ec5ab752f010377d4ff57d4296ce09e + 5e479801a05652fb; + 8b2b9b8f0911e32d65cc1770a18cbfe6effd1ff677 + 8554acf1 + 270485b203a3c1c4c967c0 + a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf4 + 2d0fcd3ec8e72558fb6cad34d3a93a7ad4b5b5940fdc77c1dfd733a1ddf5e093d5 + 2e35100e8d1e24fb; + 3e89957f9a3e8128f8743d16687b7bb8deb9bd205b + 70e04c091d205c + dad9e9a79b1abf91b0851e5ca605ac84513995 + 87011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397ab + fc2c1515c5fc3f727fb3e98ba249a076c3da8668f5e89db6e7956de064 + a2411e499cacffef; +} + +des3-ocb1 { + 60d7bcda163547d348b7551195e7 + 7022907dd1dff7da + "" + "" + "" + cbd24ffb264f16ad; + c5c9941d26d0c6eb14ad568f86ed + d1dc9268eeee5332 + 85 + "" + "" + a6e1ad4b16d8d99b; + a6ed810c9b689daaa9060d2d4b60 + 03062365b0a54364 + "" + c7 + a2 + df1618790e682c74; + 6c160f11896c4794846ecfa14a71 + 30c9f137120634c9 + "" + 519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29 + 51d9c953558e88ed892717edb5839471bab17ebda859fa2d + 673b34362686d614; + 549e6b0d27a4ba234085406a6136 + 512061f7080cc07d + f0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62 + c9269029df3e6057acc87638f508046733d9ff61cdbda3b3 + 9e9db1333c288d89f1d852453679fd4a9df932ee424b56e6 + 0e15cfad6c6299f4; + e9878731ebfedd4705e505da1435 + dceaa7b1cc49ae1d + "" + 50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b0009 + 79f213b6e9d3b4a233652364a0741f0a3905112cdcc65fc6a1f02b20e1 + fb385d47f056ea7a; + 61040ef2f9b2fc5fa450727a9b54 + 2cde52ebfda19d0c + cc520f215eb57bb3a4f3ebbbb18ac6c95a97a4 + 8030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605f + 1b7e1e5164841c4478deb10a87cc07f70db15af1b12790fb9f8ea16d79 + e0d1715f5e9373c7; + aee2b03fb648e27f + ff63102758fe2b69 + "" + "" + "" + 4b884a39fbc7c745; + ac26afa3349829b9 + 4586306fed54154f + 8f + "" + "" + d445ece0ef590e55; + 28523c03d4de1600 + 157846b710ee7280 + "" + 7a + 0e + 020e28ecb1a51fd3; + 2219bfb474fd71d8 + 91f24bb65d156325 + "" + 9f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77 + a683ff420e8f9ea9467dd595afc344a0d25d20ea01c93b21 + 2748703cfe3e8226; + dba189196d1ebba1 + 0b0467cb9fc2712a + 199e533fa9156308cdec3f768281e040a9b9a222bd689aef + 66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa + aad5b6cbb6216005d17943984bb41bc4b6ba873ca43cb46b + d2c66cd04f05868e; + 6a5cfb0bad7d9521 + 4ade49cb3b6f5fe8 + "" + 368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b533768 + db8d34944ff3c0cdda5436416fb627c58f9b02d925b59a9b68fbbeda2a + 06b84a7b2c9665a4; + 5a96ed65b9aca338 + 527ef19b09c063c4 + 6f88de9fd41e72d7b97e23e6eabdff3bcd2114 + 99268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d + db5cd9c16b245b3b5078d900f5d270cb81567d73703c2c95925a7237d3 + eef56cad5b7f2ed2; + 7100b8b649377d20a8f083455b663e4e + e1315f3c8f2aebfa + "" + "" + "" + 56ad76ec7f013571; + 921451dcd1af5813b70d30ce2f1fef6e + f315d0798391805d + a0 + "" + "" + 6542ea8693b8cd18; + 8da3aefc5f8584b7c5e617669c0f16e3 + 9815d4e9cfce3ed1 + "" + ec + 35 + 90d173ba8349a22b; + df3d264a7f16cb16c2e815f422cdf0c8 + e30308be3c31e6bc + "" + 58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed1 + 64348fc5f46a28edab91b5d41e27ab352fa8ca90d322b603 + b894f7a0cf918ae2; + 2ca986981a874498ad0abef8bc4fcb70 + e27e98ef1f0446b4 + 2fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae + 985511265febd11c164720eef9eb1c8dd0b00951f2846490 + dc70ae429c73fd871a49ab5aea8ed37196a151ad8d09dc3c + f76847ab0c01c5bd; + 16ed00456331854bc78bf43966eb0cfa + 9138ddc399084456 + "" + 08fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa0 + 7fcb46d49d63ecf4d49c4578841b1cc435362eb989098c8729fa7c8b7c + 170621267d144a86; + 89c3f9099c5ffb824173d7634c04226f + 30cbb7f0e4a973a8 + cd190107314717a77456f3ff669c732b58db8f + 48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc + b0ecb19f5804122fb10b38ce2354dd1b9001c8e4f96d9f3a8b054ef79b + e3cfbcf2b101c897; + 69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4f + fa91544485f1a125 + "" + "" + "" + efc673f15d727525; + 8b2b9b8f0911e32d65cc1770a18cbfe6effd1ff677 + 8554acf1270485b2 + 03 + "" + "" + 4be4ef9aa08e493e; + a3c1c4c967c0a458cb948bdd409b687fa3a6827b48 + 0aa3a4c84cef64f6 + "" + c9 + 60 + 3c76403cf147a5a0; + b53bf8f957f4b03cf43e89957f9a3e8128f8743d16 + 687b7bb8deb9bd20 + "" + 5b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac84 + 6a5f5444d206a359b01efa29f51c6d3f13c050b663f1ea32 + 4ed8de43ccd151ef; + 51399587011677508a15dde524af3e2bee0646541a + 42c2ecccb44d65ba + d397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf + 7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd2501 + db5dbdd217bb8761aea78de2a51b9ab2bcb9559bfae22dfa + 002834c8f3b3d2f1; + 4107c8e7d715a92add9589d1f5c054b2d983514605 + ec590294a319b980 + "" + 2068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59 + 9a6b4f24093acdff2a03f9a40494e1e6dd2ed10be75cdf9fb4381f7a1e + c492487046c80434; + a332ba58d5d5589bfe079753ee1a957eb6d6699e6b + 7ea2725cb2dac07e + cde95759ac46fee6dda7abc8ad68daac90cfe2 + 2d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e6 + 14bc7ec21221fab0d0a55be9d505c315ef5ef5a01c9a5d8c71c6a8a569 + 598c7a7659a4ece7; +} + +des3-pmac1 { + 60d7bcda163547d348b7551195e7 + "" + 4ee97adb08a4f1ca; + 7022907dd1dff7dac5c9941d26d0 + c6 + 9280792119f1c90a; + eb14ad568f86edd1dc9268eeee53 + 3285a6ed810c9b689daaa9060d2d4b6003062365b0a54364 + d3b9cda12ef855c9; + c76c160f11896c4794846ecfa14a + 7130c9f137120634c9519848a877ff77bf7919 + ccb225988c72647f; + 2a5b50ade5d9cd73 + "" + 29b6cbd6a39de3ea; + 9a3d1f337f29549e + 6b + a44255ba14c7c82e; + 0d27a4ba23408540 + 6a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8 + 4ae6eee38bf7dfc3; + e160ad10997a2163 + 5c6d62c9269029df3e6057acc87638f5080467 + de786269abfb7dce; + 33d9ff61cdbda3b3e9878731ebfedd47 + "" + 8e4e4d58688d0661; + 05e505da1435dceaa7b1cc49ae1d50c3 + 82 + 1eb3af80bd877e09; + 01a894476b3f102b752eb9529533966f + 27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b54 + ba1f17ab53c77f9c; + 2cde52ebfda19d0ccc520f215eb57bb3 + a4f3ebbbb18ac6c95a97a48030370c33d090c5 + 614b8997f580de04; + 4215abd6b3ad54efc9a38378c5b93bf4f2aad2605f + "" + 79469a20ba34f900; + aee2b03fb648e27fff63102758fe2b69ac26afa334 + 98 + 69f377b3ea8e925c; + 29b94586306fed54154f8f28523c03d4de16001578 + 46b710ee72807a2219bfb474fd71d891f24bb65d1563259f + 6e0adaf190bd2ea1; + 9eb53b571ea629c54d57dd2d42f70800df9fcbaca4 + 8b77dba189196d1ebba10b0467cb9fc2712a19 + 129deaeec0e03d30; +} + +des3-ocb3 { + 60d7bcda163547d348b7551195e7 + 7022907dd1df + "" + "" + "" + 9bd7647cc6fc5088; + f7dac5c9941d26d0c6eb14ad568f + 86edd1dc9268 + ee + "" + "" + 651a2beca10057bf; + ee533285a6ed810c9b689daaa906 + 0d2d4b600306 + "" + 23 + 61 + 55bdc89a749be10d; + 65b0a54364c76c160f11896c4794 + 846ecf + "" + a14a7130c9f137120634c9519848a877ff77bf79192a5b50 + 04994fd2405c66040b24f1e112d12a373a5ded3204e93dfc + 4d28060d06c1e6c9; + ade5d9cd739a3d1f337f29549e6b + 0d27a4ba23 + 4085406a6136512061f7080cc07df0591d8fa21f2dd88374 + d8cde8e160ad10997a21635c6d62c9269029df3e6057acc8 + bd32ead43e0c7e3cdf30ec74e82e9db51a480c4bce6dfdfe + 2440122fa77e088a; + 7638f508046733d9ff61cdbda3b3 + e9878731ebfe + "" + dd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752e + e7086ac5c54bba010b3597e95d8035ba213d20c55f50558f13f3725cb8 + 5f2cd9483cb3a2ac; + b9529533966f27043eb621b7f65b + 000961040ef2 + f9b2fc5fa450727a9b542cde52ebfda19d0ccc + 520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215ab + 960f222b5a4b66a7a416bf51be1cbfbaffd7626fd3449cfac5ec66cd94 + 0cfa7a7a8b52f6d3; + d6b3ad54efc9a383 + 78c5b93bf4f2 + "" + "" + "" + f3be635a1f9bbcfa; + aad2605faee2b03f + b648e27fff63 + 10 + "" + "" + 27972bc75183a1f2; + 2758fe2b69ac26af + a3349829b945 + "" + 86 + 6d + 1449c4672751ce11; + 306fed54154f8f28 + 523c03 + "" + d4de1600157846b710ee72807a2219bfb474fd71d891f24b + 2f9edc04b832738964e4ef2c18a17b1eaf8ec0a325e08b9d + df25c2d0f9430d6f; + b65d1563259f9eb5 + 3b571ea629 + c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba1 + 0b0467cb9fc2712a199e533fa9156308cdec3f768281e040 + c6b34746675339e4f07cc680e5b8e3e5da5541a92c659459 + a6d7adc34d54cb89; + a9b9a222bd689aef + 66f5306ceb0c + "" + 6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49 + 79c706a66a8ebc8376e149588ab5584dcc7d59a37782abce2725bf2831 + 9d6ffb6e4cb098a5; + cb3b6f5fe8368131 + 115c037ba323 + fe1dc8151784873f0eb5b647da6794c18b5337 + 685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6 + da06bb4d2dc9612e2b9e1f38b4a9cf88c5f93c0ebbc12dc6894c42fb73 + 86be658d949b0120; + eabdff3bcd211499268878dbf30f1dad + 89d4b9b12012 + "" + "" + "" + a2599ce8b6a5832e; + e4713df46795630e7952d22bb02d7100 + b8b649377d20 + a8 + "" + "" + 1b9d7c64f893467a; + f083455b663e4ee1315f3c8f2aebfa92 + 1451dcd1af58 + "" + 13 + d4 + 7702114c8465f527; + b70d30ce2f1fef6ef315d0798391805d + a08da3 + "" + aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf + 23275152a0a4c447adf86084cad8e537778f46150a4430aa + a44aba0c5685823a; + 3d264a7f16cb16c2e815f422cdf0c8e3 + 0308be3c31 + e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd5214 + 7ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f04 + 55917e61b80378e828b2cb53911b751df969fb0aaf39a0a1 + cc006e8fa8f47da1; + 46b42fb144d44b6d00f06dc188d472a7 + 84e0c6f21195 + "" + a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016 + 67426920d7bb581d90c8c9b561d504d9729a024b2d26a34233f624bf35 + 3e0e6eaf9b8d41c2; + ed00456331854bc78bf43966eb0cfa91 + 38ddc3990844 + 5608fe95e81c2533e31c9c1a9851bc2810d858 + cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cb + 42eff82d31f0ca1cb79604219601c56c9d4e60ea08ab0e2be33b87fd70 + 70e2f64112ef6d62; + b7f0e4a973a8cd190107314717a77456f3ff669c73 + 2b58db8f48af + "" + "" + "" + f8608b8da49f9700; + 65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2 + f294b38766fc + 69 + "" + "" + df345d63832f4e3d; + f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa + 91544485f1a1 + "" + 25 + eb + 17c6a45486274633; + 8b2b9b8f0911e32d65cc1770a18cbfe6effd1ff677 + 8554ac + "" + f1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6 + 359c9f7d642db7d7d35ed57a183a25212c054d25a4de09e3 + 065d208592dbdc5c; + 827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf4 + 3e89957f9a + 3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cda + d9e9a79b1abf91b0851e5ca605ac8451399587011677508a + 271c63ace6900ca3d2ea38737ff73f9298b4f6484ff4c916 + 32315b959ad39d8f; + 15dde524af3e2bee0646541a42c2ecccb44d65bad3 + 97abfaf529ee + "" + 41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdc + 0a1bc356fb7cbe2959c09e1c504326d0544a16fa91596ca1bfbf69cd9f + 0c1a33dffaebcbb8; + ccd213e33f7e8a5718fd25014107c8e7d715a92add + 9589d1f5c054 + b2d983514605ec590294a319b9802068a9f891 + bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5 + 0e2f842eda3840dd0b22d2e5ec4e7280d96916ca08fa43b74ce34d1be9 + 32dc28ff4706c6fb; +} + +des3-ocb3-mct { + 24 d3d27b14989225a9; + 21 eb3be38e3517c6d1; + 16 07135a64481e5862; + 14 812edbcd44bd9e1a; + 8 d3d27b14989225a9; + 7 eb3be38e3517c6d1; + 24 70d5d3c75417; + 21 93e83240fae6; + 16 58382ba741ab; + 14 6c492c0d482a; + 8 70d5d3c75417; + 7 93e83240fae6; + 24 bdc8b8e1; + 21 4407c007; + 16 0654310f; + 14 e2591768; + 8 bdc8b8e1; + 7 4407c007; +} diff --git a/symm/t/desx b/symm/t/desx index 0f640861..70bb2227 100644 --- a/symm/t/desx +++ b/symm/t/desx @@ -20,3 +20,909 @@ desx { 00451338957377 4e6f772069732074 3fa40e8a984d4815; 0123456789abcdef 4e6f772069732074 3fa40e8a984d4815; } + +desx-cmac { + 60d7bcda163547d348b7551195e770 + "" + a63cd9292fdf838b; + 22907dd1dff7dac5c9941d26d0c6eb + 14 + a750bb7618266464; + ad568f86edd1dc9268eeee533285a6 + ed810c9b689daaa9060d2d4b6003062365b0a54364c76c16 + 46adc2fa0e79b3b1; + 0f11896c4794846ecfa14a7130c9f1 + 37120634c9519848a877ff77bf79192a5b50ad + 68ba5dd6b52f40fb; + e5d9cd739a3d1f33 + "" + 3480b2e14686a332; + 7f29549e6b0d27a4 + ba + 9bbb98b5d49df72c; + 234085406a613651 + 2061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10 + f2c52f3919204c2b; + 997a21635c6d62c9 + 269029df3e6057acc87638f508046733d9ff61 + e5acddb871d45625; + cdbda3b3e9878731ebfedd4705e505da + "" + 08febcce60b0e724; + 1435dceaa7b1cc49ae1d50c38201a894 + 47 + 80bdb1521243c0b1; + 6b3f102b752eb9529533966f27043eb6 + 21b7f65b000961040ef2f9b2fc5fa450727a9b542cde52eb + 86e00e79a5a63fc9; + fda19d0ccc520f215eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6 + 9b4ee9b29a9da89c; + b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648 + "" + 00413cee3fc9338f; + e27fff63102758fe2b69ac26afa3349829b94586306fed + 54 + f0bda4592cdc8ed1; + 154f8f28523c03d4de1600157846b710ee72807a2219bf + b474fd71d891f24bb65d1563259f9eb53b571ea629c54d57 + 88158a6ce8f67fb2; + dd2d42f70800df9fcbaca48b77dba189196d1ebba10b04 + 67cb9fc2712a199e533fa9156308cdec3f7682 + ebda61b856727ef6; +} + +desx-ccm { + 60d7bcda163547d348b7551195e770 + 22907d + "" + "" + "" + 8ec46476; + d1dff7dac5c9941d26d0c6eb14ad56 + 8f86ed + d1 + "" + "" + 5f3af780; + dc9268eeee533285a6ed810c9b689d + aaa906 + "" + 0d + 81 + 6bf70ba0; + 2d4b6003062365b0a54364c76c160f + 11896c4794 + 846ecfa14a7130c9f137120634c9519848a877ff77bf7919 + 2a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + 0d411f5b72112442088bee58587f1b0acc6cdc2609b38528 + 263feadb0d5a70aa; + 406a6136512061f7080cc07df0591d + 8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c92690 + 29df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + 0b9ff20737a20741c3caa6bdad16930cce5fdbe1754d211e15701f547f + 97f1a547f1179100; + 05e505da1435dcea + a7b1cc + "" + "" + "" + 001cf051; + 49ae1d50c38201a8 + 94476b + 3f + "" + "" + f4d9c98e; + 102b752eb9529533 + 966f27 + "" + 04 + a0 + a8ed8162; + 3eb621b7f65b0009 + 61040ef2f9 + b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57b + b3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6 + ab9b7c746d2bc3d9987a625049e1e17f09268f61914db075 + af163edd14717f26; + b3ad54efc9a38378 + c5b93bf4f2 + aad2605faee2b03fb648e27fff63102758fe2b + 69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846 + 222e460a7c0c877a3c3043bf46cd87c4b76b2dd7491d3d4dd22c8ea42f + c0d94d90dade32cb; + b710ee72807a2219bfb474fd71d891f2 + 4bb65d + "" + "" + "" + bd9bb6dc; + 1563259f9eb53b571ea629c54d57dd2d + 42f708 + 00 + "" + "" + f24fb66d; + df9fcbaca48b77dba189196d1ebba10b + 0467cb + "" + 9f + cc + 099a7f96; + c2712a199e533fa9156308cdec3f7682 + 81e040a9b9 + a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42 + bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe83681 + 15c1c73b28a6b905f4b301d941b961156ea6f145334295df + b81b11f44423b169; + 31115c037ba323fe1dc8151784873f0e + b5b647da67 + 94c18b5337685a96ed65b9aca338527ef19b09 + c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f + 3999f0ebfb02f3e9163b462d325a844ada24367ab139617a32a4ac7f69 + d7d9bc4926dce5fe; + 1dad89d4b9b12012e4713df46795630e7952d22bb02d71 + 00b8b6 + "" + "" + "" + e2278b44; + 49377d20a8f083455b663e4ee1315f3c8f2aebfa921451 + dcd1af + 58 + "" + "" + eb62b54e; + 13b70d30ce2f1fef6ef315d0798391805da08da3aefc5f + 8584b7 + "" + c5 + d7 + 72d0dd81; + e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb + 16c2e815f4 + 22cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479 + a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8 + e709032bd184e5104714acdbd444b4ba1242692f504e8bbd + 0e8982b121c86359; + bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188 + d472a784e0 + c6f21195a3b9f4ae985511265febd11c164720 + eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa + 157111d7f22ece6942850acb95f131f9749eb8625c0b6cef13fc859b62 + 690bf035ddf2b2db; +} + +desx-eax { + 60d7bcda163547d348b7551195e770 + "" + "" + "" + "" + ee1840d22093ec87; + 22907dd1dff7dac5c9941d26d0c6eb + 14 + "" + "" + "" + 46bb7bcd888d7699; + ad568f86edd1dc9268eeee533285a6 + "" + ed + "" + "" + 64df2aefb68d65ae; + 810c9b689daaa9060d2d4b60030623 + "" + "" + 65 + bb + 575efecd423272be; + b0a54364c76c160f11896c4794846e + cfa14a7130c9f137 + 120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d + 1f337f29549e6b0d27a4ba234085406a6136512061f7080c + 2972fa4117846aea7de02f73eb27981c4b72524b1d8bfb72 + abd123bd49b7e2e9; + c07df0591d8fa21f2dd88374d8cde8 + e160ad10997a21 + 635c6d62c9269029df3e6057acc87638f50804 + 6733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49 + 35a431ef317b963514e1de6dfb568191eaa1bc89028e5868bcd25a8a3c + 2693b4f76100e1df; + ae1d50c38201a894 + "" + "" + "" + "" + c9fb343d394b7356; + 476b3f102b752eb9 + 52 + "" + "" + "" + 47b15722772ba414; + 9533966f27043eb6 + "" + 21 + "" + "" + 0d4b68956fb6f426; + b7f65b000961040e + "" + "" + f2 + dd + 8371e2b42301e2b0; + f9b2fc5fa450727a + 9b542cde52ebfda1 + 9d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a4803037 + 0c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2 + c199728a8cd014558621fcda5a5ce7765ba3770b43832210 + 84815299c2507a60; + 605faee2b03fb648 + e27fff63102758 + fe2b69ac26afa3349829b94586306fed54154f + 8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24b + bd352eea02065aa6352132121df385b3135e6598f1bbb589ed2c6044f1 + 6993814a37fada84; + b65d1563259f9eb53b571ea629c54d57 + "" + "" + "" + "" + 0a53de56ab1af32b; + dd2d42f70800df9fcbaca48b77dba189 + 19 + "" + "" + "" + 2539d47126f0cf9f; + 6d1ebba10b0467cb9fc2712a199e533f + "" + a9 + "" + "" + 395bc02e7eefec9a; + 156308cdec3f768281e040a9b9a222bd + "" + "" + 68 + ba + eb13f2c72c06d835; + 9aef66f5306ceb0c6b08ac8b0a22260c + 571b4a42bb8fdb23 + 3bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c03 + 7ba323fe1dc8151784873f0eb5b647da6794c18b5337685a + be11a99ec28d932e8064d57a7d3b6530cb137b8c05c397f2 + 9e116a03c63831e0; + 96ed65b9aca338527ef19b09c063c46f + 88de9fd41e72d7 + b97e23e6eabdff3bcd211499268878dbf30f1d + ad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20 + 87f8e65dcf6034314eba4a952e6a6d0fc7595318f0cde2ba027276421e + 0c029e501b79f342; + a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af58 + "" + "" + "" + "" + f784fa0ed911d8ec; + 13b70d30ce2f1fef6ef315d0798391805da08da3aefc5f + 85 + "" + "" + "" + 14998b9f57e85a91; + 84b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a + "" + 7f + "" + "" + eaad2aaf758ba8cb; + 16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7ca + "" + "" + dc + c6 + 05378e1a70ab191a; + b658b970e47479a684b5aefa69a4cd52147ed12ca98698 + 1a874498ad0abef8 + bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d4 + 72a784e0c6f21195a3b9f4ae985511265febd11c164720ee + c5f5009fdbade4e487e8440429fc86aa782937bcdec0ca08 + 6feaef25c63b0802; + f9eb1c8dd0b00951f284649016ed00456331854bc78bf4 + 3966eb0cfa9138 + ddc39908445608fe95e81c2533e31c9c1a9851 + bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c + bf860edf5f2e423766bd979b97a8b90082ad8f015e2c24997603fe75e7 + 783c8dbade8c11f5; +} + +desx-gcm { + 60d7bcda163547d348b7551195e770 + "" + "" + "" + "" + 3cbc7b1df84dfef7; + 22907dd1dff7dac5c9941d26d0c6eb + 14 + "" + "" + "" + 37276edd9916fab0; + ad568f86edd1dc9268eeee533285a6 + "" + ed + "" + "" + 88e93bc3d86c7bf8; + 810c9b689daaa9060d2d4b60030623 + "" + "" + 65 + 4b + 742b8f2a4982002f; + b0a54364c76c160f11896c4794846e + cfa14a7130c9f137 + 120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d + 1f337f29549e6b0d27a4ba234085406a6136512061f7080c + ae84aba1c0a431bfee3521370654d195518e43fbbcae082e + 8ae1456ca69792a7; + c07df0591d8fa21f2dd88374d8cde8 + e160ad10 + 997a21635c6d62c9269029 + df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da14 + 4f97aead4260eff9a4c1e39ef827ce568f08fcb95f2245503953f5c1e5b02036fb + b685fc67d7bac453; + 35dceaa7b1cc49ae1d50c38201a894 + 476b3f102b752e + b9529533966f27043eb621b7f65b000961040e + f2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3 + e8df8e4af153dbf70d1517d2f6d388f02705dd53c25b7f5c9d7c6c60f8 + fa07533070e3b62b; + ebbbb18ac6c95a97 + "" + "" + "" + "" + 52880f24cb1c97c4; + a48030370c33d090 + c5 + "" + "" + "" + ea8c5fd1be78bb6b; + 4215abd6b3ad54ef + "" + c9 + "" + "" + 6130a7a2a73d2517; + a38378c5b93bf4f2 + "" + "" + aa + bf + 6a2baada10b09a4f; + d2605faee2b03fb6 + 48e27fff63102758 + fe2b69ac26afa3349829b94586306fed54154f8f28523c03 + d4de1600157846b710ee72807a2219bfb474fd71d891f24b + 353616debc97a081ea320a9a6379498465389fc12a30c97e + 29ae2d4f192ff073; + b65d1563259f9eb5 + 3b571ea6 + 29c54d57dd2d42f70800df + 9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f + e098b62b321e856c615d30d670b21afbbecc1c01d58184165b0d766819f149ff4d + afd78ddc422cde3b; + 768281e040a9b9a2 + 22bd689aef66f5 + 306ceb0c6b08ac8b0a22260c571b4a42bb8fdb + 233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe + 44c55447399ff836d71fa8adc5975f7fe504a62f8a031d118e9bdb8592 + 3aec6e5c527595ee; + 1dc8151784873f0eb5b647da6794c18b + "" + "" + "" + "" + b649714dae520d42; + 5337685a96ed65b9aca338527ef19b09 + c0 + "" + "" + "" + 0f7b54a0f0e759de; + 63c46f88de9fd41e72d7b97e23e6eabd + "" + ff + "" + "" + b5332afef45bc1e2; + 3bcd211499268878dbf30f1dad89d4b9 + "" + "" + b1 + d9 + 7d02b1fcfd1d0d3e; + 2012e4713df46795630e7952d22bb02d + 7100b8b649377d20 + a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813 + b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584 + 902dda67a4bf1b44cc8f2b788541da0946d53815390326c4 + b2a841f844b8b948; + b7c5e617669c0f16e39815d4e9cfce3e + d1ecdf3d + 264a7f16cb16c2e815f422 + cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd5214 + cfb2568095e376c9f50aed2f781748b98a68629a13f81842b6ed3315fe03633a37 + 9188774ecda5437a; + 7ed12ca986981a874498ad0abef8bc4f + cb70e27e98ef1f + 0446b42fb144d44b6d00f06dc188d472a784e0 + c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f2 + be0fd7ae8afa1502f49e7616bd5a20956f3ce40c05b3ec395eefc2ee91 + d16dddd5c97d9dad; + 84649016ed00456331854bc78bf43966eb0cfa9138ddc3 + "" + "" + "" + "" + 35514c76e6059f2d; + 9908445608fe95e81c2533e31c9c1a9851bc2810d858cb + bc + "" + "" + "" + 88e733af8182afbd; + 8424d126b807e6daa089c3f9099c5ffb824173d7634c04 + "" + 22 + "" + "" + fa4d035dde2e7d7c; + 6f30cbb7f0e4a973a8cd190107314717a77456f3ff669c + "" + "" + 73 + 45 + 706978229672282f; + 2b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597 + f56ccbb2f294b387 + 66fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa + 91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6ef + 9b5a4d527d5bc4c52350bb496dcbda3b072b99173b55d90d + 9b96c04ec2f5504e; + fd1ff6778554acf1270485b203a3c1c4c967c0a458cb94 + 8bdd409b + 687fa3a6827b480aa3a4c8 + 4cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd + 63b58db88053af9da1f93879beea44bee6faa6a2c672aefc6ec5517b273cecda73 + edbc4b6c82c99d4d; + 205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605 + ac845139958701 + 1677508a15dde524af3e2bee0646541a42c2ec + ccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf + e6bc35974509d938a953ad32ae829a5cced3f2846e756fbc99247ae1d5 + 623e465c7913e6b2; +} + +desx-ocb1 { + 60d7bcda163547d348b7551195e770 + 22907dd1dff7dac5 + "" + "" + "" + caa9db9c2fd96b20; + c9941d26d0c6eb14ad568f86edd1dc + 9268eeee533285a6 + ed + "" + "" + e3f19e04d004771a; + 810c9b689daaa9060d2d4b60030623 + 65b0a54364c76c16 + "" + 0f + ce + 274fa8d10ec38416; + 11896c4794846ecfa14a7130c9f137 + 120634c9519848a8 + "" + 77ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d + 286bf711ca2f9d9e6e3ea11390d46225834d56c3cadef9f3 + 8a3e9e27a8bd1267; + 27a4ba234085406a6136512061f708 + 0cc07df0591d8fa2 + 1f2dd88374d8cde8e160ad10997a21635c6d62c9269029df + 3e6057acc87638f508046733d9ff61cdbda3b3e9878731eb + e9a1c82381cb138e2b635f58ec9ad77e81eee97cb9b725cf + 2c08bbda5c67ae28; + fedd4705e505da1435dceaa7b1cc49 + ae1d50c38201a894 + "" + 476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2 + 77c71af12f7e75599be17868608c1e66a767d5324a43d136777c8298f2 + da3b49f25c22648f; + fc5fa450727a9b542cde52ebfda19d + 0ccc520f215eb57b + b3a4f3ebbbb18ac6c95a97a48030370c33d090 + c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e2 + e93425b446b6e0ee7622d56eb8781430e61c0b79fbf75b5129e66be0df + aaae9e5df22ffd66; + 7fff63102758fe2b + 69ac26afa3349829 + "" + "" + "" + 2454c6d4af0543c6; + b94586306fed5415 + 4f8f28523c03d4de + 16 + "" + "" + 57f09f05b22aed2a; + 00157846b710ee72 + 807a2219bfb474fd + "" + 71 + 07 + 98a03e06427d6c6e; + d891f24bb65d1563 + 259f9eb53b571ea6 + "" + 29c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebb + 79bc018164ccf90123ed426c5e261171c67c69512e8f41b1 + d83eb8863b890872; + a10b0467cb9fc271 + 2a199e533fa91563 + 08cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b + 08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95 + 2b050493ae97a338a539cf0a46f443a137a90bce681c3cf7 + cca806fe40ecdf0d; + 214ade49cb3b6f5f + e8368131115c037b + "" + a323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca3 + 49d25f8e34f3dfac53f8409552f42c89167889d2cbe2af5ba0ba4c2dfc + 7051575c9d170e37; + 38527ef19b09c063 + c46f88de9fd41e72 + d7b97e23e6eabdff3bcd211499268878dbf30f + 1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d + bfe9acab806680bdc205fdaf72e274eeec6698801454fc94a8c0c16262 + 4f53c9ecfbb5f758; + 20a8f083455b663e4ee1315f3c8f2aeb + fa921451dcd1af58 + "" + "" + "" + 0230f537d84fad83; + 13b70d30ce2f1fef6ef315d079839180 + 5da08da3aefc5f85 + 84 + "" + "" + 03faa4ac602dc7ed; + b7c5e617669c0f16e39815d4e9cfce3e + d1ecdf3d264a7f16 + "" + cb + 18 + a514a198a9c98049; + 16c2e815f422cdf0c8e30308be3c31e6 + bc58c0b7cadcb658 + "" + b970e47479a684b5aefa69a4cd52147ed12ca986981a8744 + 7fb1ffb913b75f8d4c7ea6e84a9f2fc911380d1b8ee343f6 + 2a496d014b16a40a; + 98ad0abef8bc4fcb70e27e98ef1f0446 + b42fb144d44b6d00 + f06dc188d472a784e0c6f21195a3b9f4ae985511265febd1 + 1c164720eef9eb1c8dd0b00951f284649016ed0045633185 + 722aa22fa02f13d32187730cb051fa3b49fcd9a308a9d453 + c59459ba824bc1a5; + 4bc78bf43966eb0cfa9138ddc3990844 + 5608fe95e81c2533 + "" + e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb + 86c1f74d4db77a90398574f168f83e6de15e6a2b7b2afa621590dc0404 + 4543ce1f721609f4; + 824173d7634c04226f30cbb7f0e4a973 + a8cd190107314717 + a77456f3ff669c732b58db8f48af65f7cc9e3f + b90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945f + cfa9cfeddbc593bd6812352a35fa31e2a53b1840ea430ee8e2085d60da + 90bfab3707b05a6a; + fd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b + 2b9b8f0911e32d65 + "" + "" + "" + 7a861a7d3af428f9; + cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1 + c4c967c0a458cb94 + 8b + "" + "" + ff1c4c7bc330ef39; + dd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f9 + 57f4b03cf43e8995 + "" + 7f + d2 + b1cb7d2102d5c32c; + 9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d20 + 5cdad9e9a79b1abf + "" + 91b0851e5ca605ac8451399587011677508a15dde524af3e + 9bdb27bbfc7389090471f3cb7051cb8d1fd530005e21a93f + 3bd9da825a402482; + 2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf + 9a05c7efedef3401 + 539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f + 7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d9 + b569d836ce07d26017bdecdc06938abe11f29988e2ee4eaa + 7c12ae284dab4140; + 83514605ec590294a319b9802068a9f891bc5ba5afabf8 + c3122d12d7ff3c41 + "" + 122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d669 + c893ff49cfec7dfa04b6c966ff8e2de2dbca702ed6cd0416b4d1e12b2a + 4f6e8bdaed610893; + 9e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad + 68daac90cfe22d2f + 1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6 + 254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b000 + e5977138d0d737d7b616047aa523dc1b7d5b5fb6fd20e26831a2f34bb8 + 6e42e08c54165845; +} + +desx-pmac1 { + 60d7bcda163547d348b7551195e770 + "" + 4af29214a7b8f451; + 22907dd1dff7dac5c9941d26d0c6eb + 14 + 497e34853501b17c; + ad568f86edd1dc9268eeee533285a6 + ed810c9b689daaa9060d2d4b6003062365b0a54364c76c16 + be4cb7dd9428ff3f; + 0f11896c4794846ecfa14a7130c9f1 + 37120634c9519848a877ff77bf79192a5b50ad + bd394b556e88691a; + e5d9cd739a3d1f33 + "" + cf37166cf40c5a63; + 7f29549e6b0d27a4 + ba + 36f50dc5278f6d48; + 234085406a613651 + 2061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10 + afa0c00f1d78a165; + 997a21635c6d62c9 + 269029df3e6057acc87638f508046733d9ff61 + 0cb5b03ffdf32b7e; + cdbda3b3e9878731ebfedd4705e505da + "" + 12307602abf4cd83; + 1435dceaa7b1cc49ae1d50c38201a894 + 47 + 7b6c2a63bc1599df; + 6b3f102b752eb9529533966f27043eb6 + 21b7f65b000961040ef2f9b2fc5fa450727a9b542cde52eb + ec16536d65cbf867; + fda19d0ccc520f215eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6 + b0548570d2b43e37; + b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648 + "" + 1e5b6857738e4db7; + e27fff63102758fe2b69ac26afa3349829b94586306fed + 54 + 3739adab4d52a786; + 154f8f28523c03d4de1600157846b710ee72807a2219bf + b474fd71d891f24bb65d1563259f9eb53b571ea629c54d57 + 54f3e5fc1458f0a3; + dd2d42f70800df9fcbaca48b77dba189196d1ebba10b04 + 67cb9fc2712a199e533fa9156308cdec3f7682 + 462473f2102f3c1d; +} + +desx-ocb3 { + 60d7bcda163547d348b7551195e770 + 22907dd1dff7 + "" + "" + "" + 421aa0e31e3c1a41; + dac5c9941d26d0c6eb14ad568f86ed + d1dc9268eeee + 53 + "" + "" + 7bb6a8ce983ccb5e; + 3285a6ed810c9b689daaa9060d2d4b + 6003062365b0 + "" + a5 + 0d + ca4e70eaefa59040; + 4364c76c160f11896c4794846ecfa1 + 4a7130 + "" + c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd + d0075d682bb032d318f435f35ed9e7e0dd2e759b18346051 + 3c5c9c5dab448848; + 739a3d1f337f29549e6b0d27a4ba23 + 4085406a61 + 36512061f7080cc07df0591d8fa21f2dd88374d8cde8e160 + ad10997a21635c6d62c9269029df3e6057acc87638f50804 + 2b0daddf1c1562ed4ec92feba5fc19abb1a7d7fe85035cc3 + b574000108612b30; + 6733d9ff61cdbda3b3e9878731ebfe + dd4705e505da + "" + 1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f + f9d6ea23faa8a36974e06d38d9061790875f1e4523e9f8eccb89dd8c13 + 73bdbd55cfa011e8; + 27043eb621b7f65b000961040ef2f9 + b2fc5fa45072 + 7a9b542cde52ebfda19d0ccc520f215eb57bb3 + a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a3 + 21b80b17c3caf1e5b5fdabe9f9ce4fec36e20cae0a9c9b1e85167041be + 68f794a0eb64f247; + 8378c5b93bf4f2aa + d2605faee2b0 + "" + "" + "" + fd8891d8d9802520; + 3fb648e27fff6310 + 2758fe2b69ac + 26 + "" + "" + ce479a676926cc17; + afa3349829b94586 + 306fed54154f + "" + 8f + d7 + d92beba1b5d650db; + 28523c03d4de1600 + 157846 + "" + b710ee72807a2219bfb474fd71d891f24bb65d1563259f9e + 6818636db15d3a46dc05078583752a6a774b1b514bdea903 + c5958bbdef31bba2; + b53b571ea629c54d + 57dd2d42f7 + 0800df9fcbaca48b77dba189196d1ebba10b0467cb9fc271 + 2a199e533fa9156308cdec3f768281e040a9b9a222bd689a + 22dfcb714017ac0ad765d20593b65444a234a59dd3fc1abb + aa605331fbc55268; + ef66f5306ceb0c6b + 08ac8b0a2226 + "" + 0c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe83681 + 40a58a44dd58cd9e44d06391edc4ec2916d3b29628c61ad9084f56cc29 + 436c5a2b1728295f; + 31115c037ba323fe + 1dc815178487 + 3f0eb5b647da6794c18b5337685a96ed65b9ac + a338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd2114 + 2b6d4c2462ad510a000d9df521066c02a81e31d5873c66343deb78fce2 + 77a855f0a7d42e18; + 99268878dbf30f1dad89d4b9b12012e4 + 713df4679563 + "" + "" + "" + 2685c7810bf996c5; + 0e7952d22bb02d7100b8b649377d20a8 + f083455b663e + 4e + "" + "" + a25ea075d7bc735a; + e1315f3c8f2aebfa921451dcd1af5813 + b70d30ce2f1f + "" + ef + ef + e4ea88484e9e6b1e; + 6ef315d0798391805da08da3aefc5f85 + 84b7c5 + "" + e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16 + fd6a65b03ae4567f3c6a94e573da790cb684b8d5bd32e3fd + 754c91fb0050e81e; + c2e815f422cdf0c8e30308be3c31e6bc + 58c0b7cadc + b658b970e47479a684b5aefa69a4cd52147ed12ca986981a + 874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b + 5c9347f1dc4853413edfe418d369932c21212122dac2955d + 92362b5fed50868c; + 6d00f06dc188d472a784e0c6f21195a3 + b9f4ae985511 + "" + 265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854b + 6f62164db8d9a857e36ca6eef9bbdcba9d01743165ee7acd87fe754d0d + a55e71bcc128168d; + c78bf43966eb0cfa9138ddc399084456 + 08fe95e81c25 + 33e31c9c1a9851bc2810d858cbbc8424d126b8 + 07e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd + 1c394e0b510d366554dd0afcb0c6b0b4e9437fb1c83355753863e2eec9 + 86560f52894b7d41; + 190107314717a77456f3ff669c732b58db8f48af65f7cc + 9e3fb90e1721 + "" + "" + "" + a4205f9ab2399111; + b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0 + 945ffd505003 + cc + "" + "" + 5078f8d6fa0e866a; + 0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911 + e32d65cc1770 + "" + a1 + 32 + 87fddf9b28a92f55; + 8cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0 + a458cb + "" + 948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8 + b1af8fefb936518c083e54b9c67363455a1f642e253c0918 + 159d0ce2b235b273; + f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8de + b9bd205b70 + e04c091d205cdad9e9a79b1abf91b0851e5ca605ac845139 + 9587011677508a15dde524af3e2bee0646541a42c2ecccb4 + ef425d80e98f3681592695628ed0a816418fa5899b1d1d42 + f29bb2c9e21839c7; + 4d65bad397abfaf529ee41cf9a05c7efedef3401539c51 + d2a90bbf7f1b + "" + fc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a9 + 2c4a2be80fd7d3f7b3b5a4ef05a6540fb6798601ad3623aaab10d0ac60 + a1ed9a02743fa18a; + 2add9589d1f5c054b2d983514605ec590294a319b98020 + 68a9f891bc5b + a5afabf8c3122d12d7ff3c41122d70d17d4569 + eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2 + 81c230d8f7e0294cbbb8fe659f94a74332801000f5b5f49b74ce635cc0 + 9d5ceb6d322cfa12; +} + +desx-ocb3-mct { + 24 b8a0fa1c0e3e1201; + 23 b8a0fa1c0e3e1201; + 16 08afcdeda8acc974; + 15 0c967b6cca833a3c; + 8 d3d27b14989225a9; + 7 eb3be38e3517c6d1; + 24 0418ab9332b6; + 23 0418ab9332b6; + 16 aff581b9de59; + 15 2b546df8e00c; + 8 70d5d3c75417; + 7 93e83240fae6; + 24 802690b2; + 23 802690b2; + 16 cf467380; + 15 c874e69c; + 8 bdc8b8e1; + 7 4407c007; +} diff --git a/symm/t/gcm b/symm/t/gcm new file mode 100644 index 00000000..cf2b1626 --- /dev/null +++ b/symm/t/gcm @@ -0,0 +1,976 @@ +### Low-level tests for GCM multiplication. + +gcm-mul64 { + cde4bef260d7bcda + 163547d348b75511 + c9ee47ed2b156ee9; + 95e77022907dd1df + f7dac5c9941d26d0 + 6dbd5c9c416492a6; + c6eb14ad568f86ed + d1dc9268eeee5332 + 08bdf4e9bf8c1f93; + 85a6ed810c9b689d + aaa9060d2d4b6003 + 0cf6ee6642648823; + 062365b0a54364c7 + 6c160f11896c4794 + 79f08ae100e469b0; + 846ecfa14a7130c9 + f137120634c95198 + 9f105828be4871c9; + 48a877ff77bf7919 + 2a5b50ade5d9cd73 + 474a0e6c8b786a42; + 9a3d1f337f29549e + 6b0d27a4ba234085 + 44071433860810ec; + 406a6136512061f7 + 080cc07df0591d8f + a09f47fee5c90487; + a21f2dd88374d8cd + e8e160ad10997a21 + d1a3ae2849f6e1b3; + 635c6d62c9269029 + df3e6057acc87638 + 4d02197152061f71; + f508046733d9ff61 + cdbda3b3e9878731 + 3b567fc5b2fad254; + ebfedd4705e505da + 1435dceaa7b1cc49 + dee51993e134cdcf; + ae1d50c38201a894 + 476b3f102b752eb9 + 8e3e6132a84c2062; + 529533966f27043e + b621b7f65b000961 + 262098e88d669837; + 040ef2f9b2fc5fa4 + 50727a9b542cde52 + ad129933b7f306e5; + ebfda19d0ccc520f + 215eb57bb3a4f3eb + 95e06cd4d7f6453a; + bbb18ac6c95a97a4 + 8030370c33d090c5 + 0acd90305b863292; + 4215abd6b3ad54ef + c9a38378c5b93bf4 + 9f21b3656650b80d; + f2aad2605faee2b0 + 3fb648e27fff6310 + 53448ad6016b5a88; + 2758fe2b69ac26af + a3349829b9458630 + 7a114f9030a64751; + 6fed54154f8f2852 + 3c03d4de16001578 + 91532dc3dcd1b8fe; + 46b710ee72807a22 + 19bfb474fd71d891 + 877c3092f14be92e; + f24bb65d1563259f + 9eb53b571ea629c5 + 26fa6c3a6205f520; + 4d57dd2d42f70800 + df9fcbaca48b77db + baa61b8ee2efee4b; + a189196d1ebba10b + 0467cb9fc2712a19 + a7b5b29b8359b2d3; + 9e533fa9156308cd + ec3f768281e040a9 + 30ae2526b8601e66; + b9a222bd689aef66 + f5306ceb0c6b08ac + 3656b2206364b85f; + 8b0a22260c571b4a + 42bb8fdb233bfa6a + 351d3f9025791fb4; + 5cfb0bad7d95214a + de49cb3b6f5fe836 + 3c571fdf110d88d3; + 8131115c037ba323 + fe1dc8151784873f + a5280a7d7bf3fbd5; + 0eb5b647da6794c1 + 8b5337685a96ed65 + 15a80ceb4c5612d9; + b9aca338527ef19b + 09c063c46f88de9f + 506d2129368b3535; + d41e72d7b97e23e6 + eabdff3bcd211499 + a9485bc115054e16; + 268878dbf30f1dad + 89d4b9b12012e471 + d33c8040301aa9d6; + 3df46795630e7952 + d22bb02d7100b8b6 + c351d03535b15a43; + 49377d20a8f08345 + 5b663e4ee1315f3c + 659490124597d0ac; + 8f2aebfa921451dc + d1af5813b70d30ce + a1265ff538452f9b; + 2f1fef6ef315d079 + 8391805da08da3ae + 090119c5295ce005; + fc5f8584b7c5e617 + 669c0f16e39815d4 + fc0d6997230f9340; + e9cfce3ed1ecdf3d + 264a7f16cb16c2e8 + 173b0d65b7f7defa; + 15f422cdf0c8e303 + 08be3c31e6bc58c0 + 95789ad1072e5991; + b7cadcb658b970e4 + 7479a684b5aefa69 + 5681dbf13399af21; + a4cd52147ed12ca9 + 86981a874498ad0a + 69266124234d8824; + bef8bc4fcb70e27e + 98ef1f0446b42fb1 + 9ce3c0c2bd679e5d; + 44d44b6d00f06dc1 + 88d472a784e0c6f2 + d4d0dde377de138c; + 1195a3b9f4ae9855 + 11265febd11c1647 + 324150243bf34600; + 20eef9eb1c8dd0b0 + 0951f284649016ed + 15cb17aa733f44ba; + 00456331854bc78b + f43966eb0cfa9138 + 4c8fd598a01bf479; + ddc39908445608fe + 95e81c2533e31c9c + 5341133994016920; + 1a9851bc2810d858 + cbbc8424d126b807 + 470ff40df79063ab; + e6daa089c3f9099c + 5ffb824173d7634c + 0a778cecd0cafb7a; + 04226f30cbb7f0e4 + a973a8cd19010731 + 85a0294ea292354a; + 4717a77456f3ff66 + 9c732b58db8f48af + 636a37a3d5c97941; + 65f7cc9e3fb90e17 + 21b730374ffc9bc5 + 64dccdd7dfb08b84; + 97f56ccbb2f294b3 + 8766fc69f6a9f2c0 + bf6f50d14cf7e5b8; + 945ffd505003cc0c + ae9ce021a5f1fa4f + 37035c953d053e5f; + fa91544485f1a125 + 8b2b9b8f0911e32d + 9c50f40823733f0b; + 65cc1770a18cbfe6 + effd1ff6778554ac + 11d7d33017171bc2; + f1270485b203a3c1 + c4c967c0a458cb94 + 75e2e1a04e3ad3d7; + 8bdd409b687fa3a6 + 827b480aa3a4c84c + e40958395d2015c9; + ef64f6c9b53bf8f9 + 57f4b03cf43e8995 + cc0ff0246e3ea756; + 7f9a3e8128f8743d + 16687b7bb8deb9bd + e7afa3631ceb1d83; + 205b70e04c091d20 + 5cdad9e9a79b1abf + 295070cfdc2c3748; +} + +gcm-mul96 { + cde4bef260d7bcda163547d3 + 48b7551195e77022907dd1df + 4eec45fb8fc3b3e39aac7aae; + f7dac5c9941d26d0c6eb14ad + 568f86edd1dc9268eeee5332 + 05134f056f51918c72e23289; + 85a6ed810c9b689daaa9060d + 2d4b6003062365b0a54364c7 + bcfba16699cf54c7b4827b8c; + 6c160f11896c4794846ecfa1 + 4a7130c9f137120634c95198 + b831f2da94b112266bd6bc3e; + 48a877ff77bf79192a5b50ad + e5d9cd739a3d1f337f29549e + 5ad06fd826c670ca741020ec; + 6b0d27a4ba234085406a6136 + 512061f7080cc07df0591d8f + e29fc44efee1497b3d29ef65; + a21f2dd88374d8cde8e160ad + 10997a21635c6d62c9269029 + 5cc40a00243b31c565f37eba; + df3e6057acc87638f5080467 + 33d9ff61cdbda3b3e9878731 + dccd19797b205b612986e298; + ebfedd4705e505da1435dcea + a7b1cc49ae1d50c38201a894 + e8be723b884eb9f69e388db1; + 476b3f102b752eb952953396 + 6f27043eb621b7f65b000961 + bc04044aaaef558b55e3dd7b; + 040ef2f9b2fc5fa450727a9b + 542cde52ebfda19d0ccc520f + de533f5f43678c1072d64ef8; + 215eb57bb3a4f3ebbbb18ac6 + c95a97a48030370c33d090c5 + 861b3f005e294a74ae9d78b5; + 4215abd6b3ad54efc9a38378 + c5b93bf4f2aad2605faee2b0 + bd3d716b1535654fc1336c3f; + 3fb648e27fff63102758fe2b + 69ac26afa3349829b9458630 + 9199c9fc5fe891d9b22fe7c5; + 6fed54154f8f28523c03d4de + 1600157846b710ee72807a22 + 66f5090ef7912cd1c4b4ebec; + 19bfb474fd71d891f24bb65d + 1563259f9eb53b571ea629c5 + 11a1ad6bd0e17aa45aa29d18; + 4d57dd2d42f70800df9fcbac + a48b77dba189196d1ebba10b + 5887206626c27472a811261c; + 0467cb9fc2712a199e533fa9 + 156308cdec3f768281e040a9 + f6c50c86da0692784633b96a; + b9a222bd689aef66f5306ceb + 0c6b08ac8b0a22260c571b4a + 6b5169d0ead2cf118bead4a1; + 42bb8fdb233bfa6a5cfb0bad + 7d95214ade49cb3b6f5fe836 + 23aeda3be39212e86bc0be3b; + 8131115c037ba323fe1dc815 + 1784873f0eb5b647da6794c1 + 711e6d0a1d2f28008b8c1ff1; + 8b5337685a96ed65b9aca338 + 527ef19b09c063c46f88de9f + 5fcf403f2c1cbd40c5a2b2bf; + d41e72d7b97e23e6eabdff3b + cd211499268878dbf30f1dad + 8f025a46e6a1c48a74cad7a4; + 89d4b9b12012e4713df46795 + 630e7952d22bb02d7100b8b6 + e147d342d3feee155226d69b; + 49377d20a8f083455b663e4e + e1315f3c8f2aebfa921451dc + bd0327387c43f688f66cdbbe; + d1af5813b70d30ce2f1fef6e + f315d0798391805da08da3ae + 08fa0a0c901d0d0965968170; + fc5f8584b7c5e617669c0f16 + e39815d4e9cfce3ed1ecdf3d + 98add0390bd310fa096f453f; + 264a7f16cb16c2e815f422cd + f0c8e30308be3c31e6bc58c0 + cd186496b610dd8764aa152d; + b7cadcb658b970e47479a684 + b5aefa69a4cd52147ed12ca9 + c2de0b36d4dea7af5bbaf035; + 86981a874498ad0abef8bc4f + cb70e27e98ef1f0446b42fb1 + 9d2ab48640b402ade690ca33; + 44d44b6d00f06dc188d472a7 + 84e0c6f21195a3b9f4ae9855 + 6c5c40b6a299efd5663d5010; + 11265febd11c164720eef9eb + 1c8dd0b00951f284649016ed + 3c0b6a72988abb596a30e347; + 00456331854bc78bf43966eb + 0cfa9138ddc39908445608fe + 7e180f9395090b8646d62aa4; + 95e81c2533e31c9c1a9851bc + 2810d858cbbc8424d126b807 + 78ae33d19f5d9ba3b2158f0a; + e6daa089c3f9099c5ffb8241 + 73d7634c04226f30cbb7f0e4 + 922a3fa3bb9704aa3cb0c627; + a973a8cd190107314717a774 + 56f3ff669c732b58db8f48af + f5996b9d374f4174367ca998; + 65f7cc9e3fb90e1721b73037 + 4ffc9bc597f56ccbb2f294b3 + 799bda7e13675b504cc15d48; + 8766fc69f6a9f2c0945ffd50 + 5003cc0cae9ce021a5f1fa4f + 62aaf766cc72b312acf6b867; + fa91544485f1a1258b2b9b8f + 0911e32d65cc1770a18cbfe6 + 5fe1f589f40181cef0aeaf9b; + effd1ff6778554acf1270485 + b203a3c1c4c967c0a458cb94 + 8847d0b844fc9063ff111626; + 8bdd409b687fa3a6827b480a + a3a4c84cef64f6c9b53bf8f9 + 1b937802f75d4ebc4f3d7a86; + 57f4b03cf43e89957f9a3e81 + 28f8743d16687b7bb8deb9bd + a53eb13d45700a7885120b81; + 205b70e04c091d205cdad9e9 + a79b1abf91b0851e5ca605ac + d448d6ac6e6eb01171b14634; + 8451399587011677508a15dd + e524af3e2bee0646541a42c2 + dab29efd14f77990ca5d724a; + ecccb44d65bad397abfaf529 + ee41cf9a05c7efedef340153 + fea1ab4c3083794c01303a23; + 9c51d2a90bbf7f1bfc338ab0 + ef5746ea8fdcccd213e33f7e + 74b7906ccadf56726f06016c; + 8a5718fd25014107c8e7d715 + a92add9589d1f5c054b2d983 + 20656261ca5136c2bf69b1d1; + 514605ec590294a319b98020 + 68a9f891bc5ba5afabf8c312 + 55d0d749027044ab80ecfb46; + 2d12d7ff3c41122d70d17d45 + 69eaff59a332ba58d5d5589b + a4de245c51057e4ca49e06d7; + fe079753ee1a957eb6d6699e + 6b7ea2725cb2dac07ecde957 + ad498f1966703fd2cbad5b6d; + 59ac46fee6dda7abc8ad68da + ac90cfe22d2f1f2968cc42fa + f415976427d6fe6ff4547d08; + 8b669ed3bb3542a9cf44bbc8 + c6254d980398bd94e66eb456 + afe3c9c5ded2010edc99564f; + 3d405e51881e99027b8ab9ae + a3ccf860b0009740763d9683 + 1ee6d3bc94ea166843327955; + 6c5f87b95460938de1288c69 + d80ea12ff4bb5f069b8a2e86 + 046ba565c8674b84f22ac9a3; + 041c1b9fc214e9ca2186ddf1 + f6a7a3aa7e740da967828e36 + 9c0b170f7e8ca9958dcfc12f; + 04b35b15ffaa6c36800d9645 + 563a308ba60076817523bd2a + cff407868fb153b9b51fface; + bf1261b089d8f23a9c283507 + 6a23faac2cdd67771cc667a8 + 7006da38a1cf3992ef37b338; + 331f0a170b66283e4f834a06 + 148f302c3973accd56f6f24e + d493d3e118362ffe57ffce5a; + 33958b8c2e2352fd61e4fa8f + ec816ac861a8b33779f09e7a + f700eeecf80cfd35a7c249c8; + 10fc02a8f48afa3080ee119a + 52a9a817e4f2b94b0820cab3 + 41f9bc5aceef5e3c164829d6; + 83a8cffeea7c486315799dc8 + 75fba578c8ec4837898a9214 + 9ab99439ea7108fdd2b3a68a; + 2b5b0677da1ac273117b45bc + fff5d5f8b6fde2893232a9f8 + ed9e4c863cac39665c322566; + 1d14517ffae475f6b94a43a6 + 7b3d380d2f9aaafe2dd721c0 + a84bebd2a47410cb5320cd55; + 095c8808847689211450ba80 + 95ffab1eaadf66fd22ac1976 + 09742e21f274088ba0c8fcc0; +} + +gcm-mul128 { + cde4bef260d7bcda163547d348b75511 + 95e77022907dd1dff7dac5c9941d26d0 + ae22821f55ada6b996c3818891f4ec1d; + c6eb14ad568f86edd1dc9268eeee5332 + 85a6ed810c9b689daaa9060d2d4b6003 + c23e2072f3dbef54a6d43f840a45cd25; + 062365b0a54364c76c160f11896c4794 + 846ecfa14a7130c9f137120634c95198 + e4c3bf75dfae8f6201d306bb612d2757; + 48a877ff77bf79192a5b50ade5d9cd73 + 9a3d1f337f29549e6b0d27a4ba234085 + b5e1c1885725019124e64e12a7f7a284; + 406a6136512061f7080cc07df0591d8f + a21f2dd88374d8cde8e160ad10997a21 + 83dc338673e6dce375f0c9e9c3853a3f; + 635c6d62c9269029df3e6057acc87638 + f508046733d9ff61cdbda3b3e9878731 + 48660987fa15f010812e499b7e448508; + ebfedd4705e505da1435dceaa7b1cc49 + ae1d50c38201a894476b3f102b752eb9 + 1be7a7b553d5f4e88c6bdda1162fc56b; + 529533966f27043eb621b7f65b000961 + 040ef2f9b2fc5fa450727a9b542cde52 + 7c48e4ab5e27e4f79f7c02e4e171cc2b; + ebfda19d0ccc520f215eb57bb3a4f3eb + bbb18ac6c95a97a48030370c33d090c5 + 45d12390797c08a0c3cc9244cd56b922; + 4215abd6b3ad54efc9a38378c5b93bf4 + f2aad2605faee2b03fb648e27fff6310 + c53ccfdb25d06cd49acea8481c953bb7; + 2758fe2b69ac26afa3349829b9458630 + 6fed54154f8f28523c03d4de16001578 + 413a6503df527330e38a5e62d61677da; + 46b710ee72807a2219bfb474fd71d891 + f24bb65d1563259f9eb53b571ea629c5 + 4c22f463e2528bfff499d3337d32a921; + 4d57dd2d42f70800df9fcbaca48b77db + a189196d1ebba10b0467cb9fc2712a19 + 068a3e3a1cf5552b90d915e565c76c47; + 9e533fa9156308cdec3f768281e040a9 + b9a222bd689aef66f5306ceb0c6b08ac + 1463b22c7b22f4b483ceff293a405c18; + 8b0a22260c571b4a42bb8fdb233bfa6a + 5cfb0bad7d95214ade49cb3b6f5fe836 + d1be35fea22f3168cb22d7b044c4a53b; + 8131115c037ba323fe1dc8151784873f + 0eb5b647da6794c18b5337685a96ed65 + 39ee791290bd770cc3747c82e906de45; + b9aca338527ef19b09c063c46f88de9f + d41e72d7b97e23e6eabdff3bcd211499 + 5e39550b65471a1a5a8db0a1a36ba3a6; + 268878dbf30f1dad89d4b9b12012e471 + 3df46795630e7952d22bb02d7100b8b6 + f1f7219c57aca09072abd1a4b5dc211c; + 49377d20a8f083455b663e4ee1315f3c + 8f2aebfa921451dcd1af5813b70d30ce + c53ec2fa18d6dd8749295e7246056537; + 2f1fef6ef315d0798391805da08da3ae + fc5f8584b7c5e617669c0f16e39815d4 + ba9f8b1bbaaca05549621835352a0732; + e9cfce3ed1ecdf3d264a7f16cb16c2e8 + 15f422cdf0c8e30308be3c31e6bc58c0 + e24b90e7ca7ee0094901641a6ed9efe3; + b7cadcb658b970e47479a684b5aefa69 + a4cd52147ed12ca986981a874498ad0a + 6a8831e02852976a844c69f551cd6617; + bef8bc4fcb70e27e98ef1f0446b42fb1 + 44d44b6d00f06dc188d472a784e0c6f2 + d8ede7cda85607c85ca2aa454275cab5; + 1195a3b9f4ae985511265febd11c1647 + 20eef9eb1c8dd0b00951f284649016ed + b7690610ba96abfaa395dc709830c17d; + 00456331854bc78bf43966eb0cfa9138 + ddc39908445608fe95e81c2533e31c9c + 7b23455563491e6234d7f3976ed92534; + 1a9851bc2810d858cbbc8424d126b807 + e6daa089c3f9099c5ffb824173d7634c + 4111b410f25d6c27ef36e4c0744e06dd; + 04226f30cbb7f0e4a973a8cd19010731 + 4717a77456f3ff669c732b58db8f48af + f3ed8ac5133b62dc453bb3b845371f07; + 65f7cc9e3fb90e1721b730374ffc9bc5 + 97f56ccbb2f294b38766fc69f6a9f2c0 + 97bd7eac33021557df0c54ca9b45c4b3; + 945ffd505003cc0cae9ce021a5f1fa4f + fa91544485f1a1258b2b9b8f0911e32d + 074736b8f03cfe2d058b60a60c1c42b2; + 65cc1770a18cbfe6effd1ff6778554ac + f1270485b203a3c1c4c967c0a458cb94 + e6159e8e83f7acbcd6e3c1530ec97a31; + 8bdd409b687fa3a6827b480aa3a4c84c + ef64f6c9b53bf8f957f4b03cf43e8995 + 47c1e7905f2f87b6a522a2eb83b6e7cd; + 7f9a3e8128f8743d16687b7bb8deb9bd + 205b70e04c091d205cdad9e9a79b1abf + 48d09e17f51f54cb44113d4f22d19bee; + 91b0851e5ca605ac8451399587011677 + 508a15dde524af3e2bee0646541a42c2 + 7b880e45b35f9b942de7b817ad2d3921; + ecccb44d65bad397abfaf529ee41cf9a + 05c7efedef3401539c51d2a90bbf7f1b + 0f092a20ab3a445fa314921920e68a7b; + fc338ab0ef5746ea8fdcccd213e33f7e + 8a5718fd25014107c8e7d715a92add95 + b03bdb56bcea03d7a98444d06c4d9949; + 89d1f5c054b2d983514605ec590294a3 + 19b9802068a9f891bc5ba5afabf8c312 + 7c950c3817abf217b1bb67c78dbc9ce1; + 2d12d7ff3c41122d70d17d4569eaff59 + a332ba58d5d5589bfe079753ee1a957e + 22164f3d69c20fb9a211645810a980b5; + b6d6699e6b7ea2725cb2dac07ecde957 + 59ac46fee6dda7abc8ad68daac90cfe2 + f916129ec57c478ffd99077e76fb9f0b; + 2d2f1f2968cc42fa8b669ed3bb3542a9 + cf44bbc8c6254d980398bd94e66eb456 + ccacc0839b857afecba7bbd5ca6b2e2c; + 3d405e51881e99027b8ab9aea3ccf860 + b0009740763d96836c5f87b95460938d + b5dc31fc7ae8d1a7c4b638fa22490910; + e1288c69d80ea12ff4bb5f069b8a2e86 + 041c1b9fc214e9ca2186ddf1f6a7a3aa + 9445b9b898beeb32a4d1ce0ab979c740; + 7e740da967828e3604b35b15ffaa6c36 + 800d9645563a308ba60076817523bd2a + 765a9b5e6dd62f8b3bba62382a58f149; + bf1261b089d8f23a9c2835076a23faac + 2cdd67771cc667a8331f0a170b66283e + 7ae006a4c122e24d4f7e3ff2c6f1354d; + 4f834a06148f302c3973accd56f6f24e + 33958b8c2e2352fd61e4fa8fec816ac8 + 2935d8d91408993ddb7a7d0d8db8516a; + 61a8b33779f09e7a10fc02a8f48afa30 + 80ee119a52a9a817e4f2b94b0820cab3 + ae4fd2f3a8d384e0b395461a8e326022; + 83a8cffeea7c486315799dc875fba578 + c8ec4837898a92142b5b0677da1ac273 + 9b0c75856b1c2972cb990106690d373b; + 117b45bcfff5d5f8b6fde2893232a9f8 + 1d14517ffae475f6b94a43a67b3d380d + 5b7b6a4fdfcf0c8a6d67f240458b70f3; + 2f9aaafe2dd721c0095c880884768921 + 1450ba8095ffab1eaadf66fd22ac1976 + 729752ad6453d80b3d31e7433be19add; + 063e113ab61f813e28a1397a7974a1d7 + f4220c785fe426a5a0e80f678d404147 + dc51774484281b3ab9cd2859a1f91063; + 842941feeffdc2eb44dc8c0d5e8f444f + 7f4e0c893959b74dc23a7bb40e7e0013 + 1a01406d34cf1da32e48b55e792b37e9; + e5150686d2301b43a15a84e81d7f5ced + aa49e2414ebf47970e560475cff20687 + 0e9125c21526a8dc35085476ffbd523d; + 7de69146acc3ab6cf8556b7aa7769459 + 48d1b8834df2196c92ec1718dcdeee0d + 31df775698abd477c7c389bbade1026b; + 52d9539726d2810391b3f9d10c39b07a + e8f08ce7cee4758a386a9943e97dedfb + 87800aad52281a95fb85fb4679774add; + e61e737882cd09c2b9a80f34c0fde11c + 2481b11fc76bfa4dbf710a9e544e0c53 + a3b71ba7cd2e15c70cd5d40d6d145d1b; + 6ca1e040f9ad5b04140d98edabe08485 + 290a4d87d13b07398a1458c2c6b61dbd + fdba17a43c6d190d2318855a2645748b; + bc1cccada8c1a0a9aabb6c4e3c3554f8 + fb1ef61614c270295dfc0ca6551ca4bd + c7eabdcdea64775c683fa87614816b9e; + b75359f91cb9d921056b7de74fc9a9b3 + 7154ce6c0b396179d31f06a1dd5982cb + a3fa226d9cd4183023e8061d3c3c7666; + c0d7cb23841da1ae8f4ae480cda98ad6 + cf2bacf6f9fd3f821330c43f3df6c2b3 + 635a20300e343fbd26211c9ff3ea26d5; + fac7cbcf96523d4723f91801325eb855 + 3236651c96788d73d192ee53b3f3ebd6 + 1ac40bd24b41dcc095e25dd6f5647d68; + 6ddd98cedbe88e245de25b1593b70f86 + 01562d90a9b59ed034a867642d25d547 + fe9b405f0a0e3d917075a2ce8282a881; + 56fa5c47f16f64b837bb4926214211a1 + c696ba172010abb433922a22d9fd8815 + 384b8bc7a4a1135a6bdf3c36756b0774; + 19165eb9d85197a21cc34ac0d5ae7be8 + dbf98e4ffed2cf6b1372a5aa47b54fd9 + 0b197a28af39b496a4d82db88cfa51b2; + d70c70e117bf1cae71b3a56f0e7d839e + a59cc783443d64f2ed6a29b96856beca + ab4ef17dac09d42ecaaac8d50643d89a; + 34fd6544bcf86b799e2a1681160ccf05 + 5f0fd3001da597a1406d465b7b1419ea + c964db11b22df7e476eac1448500114e; +} + +gcm-mul192 { + cde4bef260d7bcda163547d348b7551195e77022907dd1df + f7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee5332 + 3bf1ea9b1ebee7e9444aaf08e585b09b31e67d3c95c9612d; + 85a6ed810c9b689daaa9060d2d4b6003062365b0a54364c7 + 6c160f11896c4794846ecfa14a7130c9f137120634c95198 + aa859fbc2a8ddcff234ac6e350b0e0c1a62f882f77219ce3; + 48a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e + 6b0d27a4ba234085406a6136512061f7080cc07df0591d8f + 6caddb90ad1aaf422acc28e99d650fa1a3d7b480101b3b32; + a21f2dd88374d8cde8e160ad10997a21635c6d62c9269029 + df3e6057acc87638f508046733d9ff61cdbda3b3e9878731 + f8d6b247d97ac3252c49a7544bbde8a0e45a999bc81b156b; + ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894 + 476b3f102b752eb9529533966f27043eb621b7f65b000961 + 27177d063a813ad4be51f4360cb3933bf6ccc1bb64c5cb32; + 040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f + 215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5 + c03117b28345bbbbdf657e220e2f23de46743a5591e66d69; + 4215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b0 + 3fb648e27fff63102758fe2b69ac26afa3349829b9458630 + 9c0ce16e01e9376fb28c571aa2401c7be69cabc249323ab4; + 6fed54154f8f28523c03d4de1600157846b710ee72807a22 + 19bfb474fd71d891f24bb65d1563259f9eb53b571ea629c5 + e869d24bde7293357bb17686c423591a891c40eb75e9cf8c; + 4d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b + 0467cb9fc2712a199e533fa9156308cdec3f768281e040a9 + 26ca24fde1d3d37a5e3dc72acf6d2b31ab1d084caa3dc205; + b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a + 42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe836 + ee889525ce4e6531e0eb218a0e72bdad13ecc5a1842d16f6; + 8131115c037ba323fe1dc8151784873f0eb5b647da6794c1 + 8b5337685a96ed65b9aca338527ef19b09c063c46f88de9f + 12eeda395ce56e2170f6671f527f165f1992cc1940b552f7; + d41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad + 89d4b9b12012e4713df46795630e7952d22bb02d7100b8b6 + 55153969c52056416bfd39a39cd2417339c800620227b450; + 49377d20a8f083455b663e4ee1315f3c8f2aebfa921451dc + d1af5813b70d30ce2f1fef6ef315d0798391805da08da3ae + 7e3e26d9c6514465ae7258f1ed4909c83ea1bbcb8a0b2947; + fc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d + 264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0 + 8acad6c66a7d17fc4e55a164408cf9ad42974ee147d6fd0f; + b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca9 + 86981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb1 + b62791c6430580b6921bda4e8f0dc67a3cd4c344ba87a56a; + 44d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae9855 + 11265febd11c164720eef9eb1c8dd0b00951f284649016ed + 9a063e0f09a4fc2e41a63b38564fc07c578df43375a31c9b; + 00456331854bc78bf43966eb0cfa9138ddc39908445608fe + 95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807 + 6eb9bc75eb709c4a6f63d8121d25b8777f5ea3af865ce812; + e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4 + a973a8cd190107314717a77456f3ff669c732b58db8f48af + 0b3e51503a58f410adb27a6203a8966d47657d481a302d23; + 65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b3 + 8766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4f + 82de8284669677b6832d83675af4fe5462636a530459d49a; + fa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6 + effd1ff6778554acf1270485b203a3c1c4c967c0a458cb94 + 61d8b471ee449edb41627d254bfbfcbca10babbc1460d5f8; + 8bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f9 + 57f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd + 254a831b866aad0f5e51943fc70c5ccaa7b9adba85762f00; + 205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac + 8451399587011677508a15dde524af3e2bee0646541a42c2 + 418f551166e166e2e89fdc3d3a7a1e60e50e472c349da9de; + ecccb44d65bad397abfaf529ee41cf9a05c7efedef340153 + 9c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e + ecf94369195385ea66741348bd0e796c461293ad8b1d1895; + 8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983 + 514605ec590294a319b9802068a9f891bc5ba5afabf8c312 + 245f715f907f93b9b5277b55f844f5b4aa732ac698a76f95; + 2d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589b + fe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde957 + 233a36249df31b12a3da455a1ff4c34f457399aa9ae8194c; + 59ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa + 8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb456 + db7a3e16e9aafeab616ce0fd985073f9eefbcb08c69985b7; + 3d405e51881e99027b8ab9aea3ccf860b0009740763d9683 + 6c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86 + 7fc4a6d0b794e1bc893a00969479168876f166d1140aa9e7; + 041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e36 + 04b35b15ffaa6c36800d9645563a308ba60076817523bd2a + da67471cfae7c99a25eb0f23d5081e6f05888ef4c7c5651a; + bf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8 + 331f0a170b66283e4f834a06148f302c3973accd56f6f24e + 6a391d4b0a662c09d3807c90dfcb8f230e260dacb89943e0; + 33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a + 10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab3 + 8ae8f405accb95e13d86bed19e63f6d6efe47264a46960ca; + 83a8cffeea7c486315799dc875fba578c8ec4837898a9214 + 2b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f8 + 72892f188dce0da69ee68b3782ead0d40f1748fbec7dfd06; + 1d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0 + 095c8808847689211450ba8095ffab1eaadf66fd22ac1976 + 281ef0eff8afd5233318b564c8ed228e76c075ba61e7bd6b; + 063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5 + a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f + 4fa4ca4d35e133d9d94815fc1bd294792bf73d2cb470eef3; + 7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43 + a15a84e81d7f5cedaa49e2414ebf47970e560475cff20687 + 9d7c763547460f559d2ace4bc185f365e0c634e9ddffe0fd; + 7de69146acc3ab6cf8556b7aa776945948d1b8834df2196c + 92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07a + 33c5a1a6645c8ea5e2a1bd5c3d8a05ed1fbf25bc16b969b1; + e8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2 + b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c53 + 14ed2a6864c16b031fe425f0edd51930c4e09a1672e28578; + 6ca1e040f9ad5b04140d98edabe08485290a4d87d13b0739 + 8a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8 + ae886c5aa093d9c66b6de64062eccf3c5d2c3fb763bdde09; + fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921 + 056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cb + 877d80fe26e43415303f4590f934354f265aefc3aa7bf85c; + c0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f82 + 1330c43f3df6c2b3fac7cbcf96523d4723f91801325eb855 + 9ffdb8a099964dd83b1936e57a1c3511c92c68e0c712d1ba; + 3236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e24 + 5de25b1593b70f8601562d90a9b59ed034a867642d25d547 + 6bd995f6829d0ac4d313f7ab100ea03ffbac19de700dce3a; + 56fa5c47f16f64b837bb4926214211a1c696ba172010abb4 + 33922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8 + 1fbdf165adb07f53ff3ea39a33a82ab9a5cb243259c5ec1d; + dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae + 71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca + 14c2eb66e8aa8bdcd09978ebcb905473a8edff6c771da7f1; + 34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1 + 406d465b7b1419ea51cf858f938f6daafbd656445a09898e + c1f403fe552c5a3d008512eb2d015705e149072ce1d3e69a; + aa96ffc3d1d2e31e4e34c94b8bfae64825ecd75a66d88eed + b969ffe07669845ebb7a24c69f13d099f47166edf54538e8 + a033fe30ee8714a173e1fd5c821ff2c5aeaeda27c3a9dcca; + 8fbf433a7ff212085179e79771f6eee7283ab178ef2b800d + 7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901 + ecff14eb486025a840e4b7d8b43075a87de1cac31cf05804; + ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e90029 + 26ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb + 936b458a28fc0c6de0ea6f10e49cc13892899a112fa175b4; + 84241986c251f5b70be2367f047265264e0da72efe8995e6 + c932a17eab511eddb8e4ba463c663035a6ae8a7a899e4279 + c106ea40f0e1a1cab89dfd44d27bec7ad878e4bfdefb1c8a; + d54d03f0e0f3e961dcfd40088d5be74088e4097efb0368c7 + e2f431ee6988cf2a0e9ebeb3de79c4f86c9e4fba61339d6d + 5962497cc337df2622d05213a1d8a5048ad7f017cc53b01e; + 907eab7707ca48ff5ba1ae93d16225d469de5747bc1addf5 + 748729720a320fe14fd29cfc59314fe2079c0a2535ded561 + cec57ed2e38528db38facc00e2cc658f681f371ccd55af54; + 12d6e3d33dcf7c71cd7d130323794e3da84a9df69703a9ca + f02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd1 + d4186ea94ce6b6e90797ce6c5c09a2f136e758b7bbc332a0; + 8c374fc43581d2f72a89584a2404a059f7f99c7241a0c879 + d6d4455b382a9ce757b3e7a1d07585ad9d7ea9c7c9cf54f3 + 55dc606dc9bad711515603b589f1e1227c03826c0d017b3d; + bc6d94238ab56d738e02abd651477cd726d6f3ebcd6fadea + b50906642a7de6496247060e7be3632ed9bd94bb42f45a87 + 97ef18739ec98e9cff77ca3f323b567df45c8ca5e5f3b310; + 33b2cd2df9d1d905cfdb29983050d6bcdb686a0c897031ad + 09a5b8fa687ec3bad8e18dc2ad361f1e226e78876cd35f86 + 5671fca885dd004ba927253cd0342c5e0bfbdaddc608dcd0; + c639733c5cd84aed8aaebabb7e0f24edfd9710b7bca91b61 + 2ea37fc5cc09f7f62f66b423fcd2dec5de24d264f2c83983 + e587e42c1e61c6ceadea37c68bfb715e01a15c47730ac81b; + 9c1b06319f687dbc68d9f07fd41ccb4f8cde8de201ec2680 + 332bbded4883deea0b58b54bdd13c17ef292b0ded3caeb5e + 87aa1604b5d3a8bc2b6b8bc67d37a3dbfc3d12b19cbc43ae; + 57fd21df10bc6186265ee6ea45907de6cb822fb2ef953aea + 358a03e0fce2e1b9511bd332c86e67f123377a8f0256b8dc + 9e06e282ca2a9286bedf70783876f36cc238cca76cf81dab; + c73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7 + 496993a25b072945d83f923e66b0a6689cf0969c003a8fca + 54ce4a46639bb8b1627fcb98bb76270c615f5a4411c8c754; + 80e322a4b1bf050c1220450433efb6b6d8a2d820cf27a64b + 9d47f636845dac557bb3e75f3a18fb8e173416867fcd0ee7 + 0b77cb7790f367b2b8465ddec635b6d272e78c5f8670dab0; + 8ddd9236beec76d55ed58b10f91d07a037791ab96e83c4bf + 2fb5b205e592c172a5cbc19456c95c1bea6079f3867e52d6 + 3dbca1bf0639237a10ee151674812fb5a4459614d405ea17; + 63cb3884b2a0a8ff825df752423f3179bfeb89eca385f20d + dce5f1f23564672e370ffc37d400a31e8aac1d426ce10df7 + 3186bd4e2bd9b82499779406fa93fe98d2d74a9de4f94cfe; + 3c5ee478b3b63d91024780e974a8a2a0e7a36f84ab1286b6 + 27e7d01b38a84a6de738721ed80fd0d7f69fa658abb5a440 + 83f9caa8826f361ae7b7015fed42ed61d964258e4b9aa944; + d304128719b541a9451cead18e4c61d93d1f8fcc53574427 + 767396322b3bf7d02cec05093696cec07591ada462271b1d + a6cb63d9b94d2269e85bb551f019180b8daaf1461946a2f1; + 1519eedde0df37a330fe8c22ebd77705917b7e32ae88f45a + 34a8ba3037235e19a394be4d26ce47317d8087684456b4cf + 25e012b33b54bb9734315020b02651a8476dd2af54fa9e39; + c5555e925e3e7b2ebc829b2d0505ea617b0ca9531bcdb960 + 40d39040e632d562643ccb64286303040fcaf679e914eadd + b059b9be9e7700024accda083f56f569ac51e624ed72a7ed; +} + +gcm-mul256 { + cde4bef260d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0 + c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003 + 789615a0602ce0d6e57a94074e22645fcdca1c2530cdce6a3a9898eefa48f602; + 062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c95198 + 48a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + ccd7a63e0f43d900d461f137b5f9a1b797580961dfe96d9e85ce0cc154f608ee; + 406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21 + 635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731 + 5f81e704e9b04d5b517392c372c5d2756eacc4f7a9442ac98d4bf8bb8536fe89; + ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9 + 529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52 + 094e95ea9c8346285f98c6f07ddd15830aa193170953a8abc41712732c76c336; + ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5 + 4215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff6310 + 52d7772d1f860c1ce6cb4d1259577c2d43421ebfc44c89c43f05d0f424401b34; + 2758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de16001578 + 46b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c5 + ad51dbcde8d0216bc998500d67317c852d273252d39d2c6a555d22a4fd180959; + 4d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a19 + 9e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac + f25c5e462dc2a069bedb1d39ee68b16d025c0596ca27efd01c46555b245f6087; + 8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe836 + 8131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65 + 934d35daaec3791e39e799c81c62f07b1628bcd3113eecc4cc13993fad10e629; + b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499 + 268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b6 + 99845195dba2f3b005653321a028907e11f546e597a641d652d85dae95e1775e; + 49377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce + 2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4 + 16edc22df1c67d480ba3d471d61097eeba54e40ca0bf06d6fdd84232677efd19; + e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0 + b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0a + 49b59d9642e48bb2116b5b2515b77ba746e6ae804e8e9ed83ca2322a800a9ae6; + bef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f2 + 1195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed + 6d03d43d9d7afc91f749c061d63dde21753f303c5d070e34dde5193c27e13046; + 00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c + 1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c + fd315ad2958b91405b2895b81391997c56a599609bdcd17ce9f2d540689374c1; + 04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af + 65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0 + 4978b31536da1b90c44b6dfa1e874a37d4442a9e65979465998ae5ef0599fdfe; + 945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d + 65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb94 + d64e275582ac14f23502aa43a0c2819e236e28770d72f3e9fe0d91b1cfe18d2d; + 8bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e8995 + 7f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf + 32223b066ce69f5963af0f7e121424ad3ab03d818562327eb0a495e7b0a0a844; + 91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2 + ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1b + 98abd767205b0f7fe21909f48b6182430169836df1712981bc1ae96b4e5c1b2b; + fc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add95 + 89d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c312 + 35446e8c959e35b74ff4e8960a1c80c3a4fc60998fc074d3fa6d73e7787b2bdc; + 2d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957e + b6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe2 + b893278872133d6ae9370dd0c1bf7e6990438ef83b012db8b4ac0197ee115ac1; + 2d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb456 + 3d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938d + b954c35b504dd99c3f95f2778ac8c69c9516eb5ecb279f01dca0cc5b1d33528f; + e1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa + 7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2a + a947b0e3b6d5caa39dd7899d60cc739b86a306c9de07b826efe14d1565ae933c; + bf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e + 4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac8 + 93c8e6eb9eb2a085c0fe1e424c031d75e3cb3924e6636a3d0fbd97a9057b1497; + 61a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab3 + 83a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273 + 1a9447bbcab0bf9fa9d4f97b44df070a91e73465559561cf07bf66f253b74839; + 117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d + 2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976 + 19931b3731ce5cd2a6e0fd8db3528a01cf67f21c9f2b6536f617786536862f1b; + 063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147 + 842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013 + 7814dc31116b923eff0567f1898f0dcfe5db31cea5f82d371c895b9cd0e1e626; + e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff20687 + 7de69146acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d + bf48e4fcb2685f89934fe3b4e1f093795e48c129192425f8d83df0a859982026; + 52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfb + e61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c53 + 3c2f3e81bbfcfe08da13e35354b1bac0f0af0da35266c33c3a85c7cfa2ee849e; + 6ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbd + bc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bd + 975de7c5d90df79434ad560bfa1f2d3acb2bb268bad74a40f40dfb0b0cc55d80; + b75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cb + c0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3 + 778ec7881d07957cb956ee98b77f4771f0b354eee8ad6ed146dc9848bb4e5a15; + fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd6 + 6ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d547 + b41eff7927b5a1646b42fe8e7f3404366196b47be1d22a51819727a2987a12c5; + 56fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22d9fd8815 + 19165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9 + eb4d497d39f0ccce56894c544b916a5a32aabb5e8470197389918e758cf5bcbc; + d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca + 34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea + ef9fd1957ea0125681170f801a2ff55cd40c11f1d8d03e28a47d07e530518d8f; + 51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae648 + 25ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e8 + b48119d50954fe55c7cb531c051c858b91a2cc0be497434ac06f1746d05200b1; + 8fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1 + ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f3 + 417db866feb0dc25af3bbff0a733e5220044c6933507f6d68d651a77b3371083; + 1b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb + 84241986c251f5b70be2367f047265264e0da72efe8995e6c932a17eab511edd + 2093bb7f7243f7d09835512229a449b3fcfbebc4f158d1f360d61dfa33aba949; + b8e4ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd40088d5be740 + 88e4097efb0368c7e2f431ee6988cf2a0e9ebeb3de79c4f86c9e4fba61339d6d + aadd61dcffddf277215a600d2a262375b40e8e8a00d2d1ee59d656ad63eca173; + 907eab7707ca48ff5ba1ae93d16225d469de5747bc1addf5748729720a320fe1 + 4fd29cfc59314fe2079c0a2535ded56112d6e3d33dcf7c71cd7d130323794e3d + 1ddab3418f7c2e73138a161d9480144100ac8a8c453cea6cbda181416ce835c1; + a84a9df69703a9caf02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd1 + 8c374fc43581d2f72a89584a2404a059f7f99c7241a0c879d6d4455b382a9ce7 + ac62a144b60cbcee96700e35a156c4ea04e8527600094b7c7c1fa57eb67c78c5; + 57b3e7a1d07585ad9d7ea9c7c9cf54f3bc6d94238ab56d738e02abd651477cd7 + 26d6f3ebcd6fadeab50906642a7de6496247060e7be3632ed9bd94bb42f45a87 + 6ac5d880e25effaad82da8efe77ed2245c9306d82e19c9b680b0a166b13db5cb; + 33b2cd2df9d1d905cfdb29983050d6bcdb686a0c897031ad09a5b8fa687ec3ba + d8e18dc2ad361f1e226e78876cd35f86c639733c5cd84aed8aaebabb7e0f24ed + 6bc8ad093f2148dc06ee942ce06a6b6c41ad4fb2ae796f9351df4d7829d0b759; + fd9710b7bca91b612ea37fc5cc09f7f62f66b423fcd2dec5de24d264f2c83983 + 9c1b06319f687dbc68d9f07fd41ccb4f8cde8de201ec2680332bbded4883deea + 7cdba7c767a1b2e0d8ea98db6d05d0e6dc5ec4add6d68cb3a0ed213ba91fb46f; + 0b58b54bdd13c17ef292b0ded3caeb5e57fd21df10bc6186265ee6ea45907de6 + cb822fb2ef953aea358a03e0fce2e1b9511bd332c86e67f123377a8f0256b8dc + 4d19278b4626808b203535680f24d55aa0bcf39b89221ccdceef29212f738776; + c73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7496993a25b072945 + d83f923e66b0a6689cf0969c003a8fca80e322a4b1bf050c1220450433efb6b6 + e82546a97e4d982315567afa93cc9cfbed1e6a9a553fb7209ac3c0c8a0f7d2a0; + d8a2d820cf27a64b9d47f636845dac557bb3e75f3a18fb8e173416867fcd0ee7 + 8ddd9236beec76d55ed58b10f91d07a037791ab96e83c4bf2fb5b205e592c172 + 550b3822df20109989c3ad201218184ea69c16e7efc41e9ae40d163565ea52e2; + a5cbc19456c95c1bea6079f3867e52d663cb3884b2a0a8ff825df752423f3179 + bfeb89eca385f20ddce5f1f23564672e370ffc37d400a31e8aac1d426ce10df7 + b35239f297beda780ccb0168fadd0708fe02a09e29566b3cea47f8f1932321e2; + 3c5ee478b3b63d91024780e974a8a2a0e7a36f84ab1286b627e7d01b38a84a6d + e738721ed80fd0d7f69fa658abb5a440d304128719b541a9451cead18e4c61d9 + 5c8cae06450a234fd67621baf1be40de09a7ee05227b7cc527bfffb14c861641; + 3d1f8fcc53574427767396322b3bf7d02cec05093696cec07591ada462271b1d + 1519eedde0df37a330fe8c22ebd77705917b7e32ae88f45a34a8ba3037235e19 + 0d07975a21745840a9528f6ad84812f76d981c7cbd51d23295b0a4c77647955a; + a394be4d26ce47317d8087684456b4cfc5555e925e3e7b2ebc829b2d0505ea61 + 7b0ca9531bcdb96040d39040e632d562643ccb64286303040fcaf679e914eadd + b11034402f9178618471341a208717e0db49389cc10169da3bbfd18c0b155dbf; + c05af8843ce6a427b99a5dc266de31c09165237eeefe4b58cc034b9f099f0467 + 8c2a9da898b39324cd3087a651014f6796f9c4881d89e127e62221e47e57badd + a3115e01610e03d14a9aa231f0af30c2f864724a9b827bee723862a2da21f67c; + 678d490c2f320ff8fb1c42761bd439f3e96dc0ed1d5b2169912af1a4e2c533c5 + 2ba3e8c71c23a089e231480aa63c484fb34bd522397f102cb8ecf4f64e329884 + f8fb5571f45bfe48a3e0a32c0152f4cf9f05fd9b6df1b16c135ac57b53140b1f; + fe73be257a753b38200bc23f94a079bde2dd98d813655dafa15b85419d15c41a + 5153cce5d0e8c8702db2ba11927589678d4f7b8fcfad4818c411f15f45230090 + f0eb21d7c095cbb71ce2a6e98cd274161a006a321bc6516d92e292d4f9d80fe5; + 3874f9a532ee46496ae753a2340af7b91f9632fc5ae71ae18b40de751ab6b676 + 1ca16434a9935e466e11c1cb072f32a59c313dba3db646ae909a096697d9a7b0 + 2784404b966884dd1be5778471a98b8cd9ffc6fb4cef97e9f828f5a9976519ea; + 556463ff1126ebc43263391424d02739d0787e804d8f1dccf6c897a8a4843132 + 4324041b5302ccd501b538bd03d5cb5c90d1fd3f7d2be187a787032c79ed9007 + 7a286ff42bd536174d2d471c7edf52d76cc1e2149ae5e89fe7c527d1baf61024; + 64ee4ce1d3fc042c084f7d8c0c48ad7d6f1eabd0fd1ec24a88f26734d5c8d92d + bd873a8fe113090d401bea4d28ff49f10ff593adc258e091abd31b62dd173515 + c4cf640c91c885ead4d5ad0de5769f1bf2fc7cc928ddb20ecd77903e78d60296; + 8f98765970acc6602da063aae01a2a199d3a4f37a5f062d216d2053a83b5d3a0 + 488ab0d2df631b2892cdfcf9fdd0f37de9ed67179aeae82fe00009428b297b55 + fd32af281c32754a7cb4b70f0856a6a595d53df2f655dfb5d065813b658f6e49; + 3230a6d917fa0c1a233c9ebc8a4cba45b20543c540fc1b9dbce078b87a1534ac + f03897b95a3f372e9f6c5a5f2ae44a7dbce9ba43a39089de20de70d0544b5151 + d717a2d8e24c431d7322091c4afa9291e6b2f642164fb5dd41b03d63eb3991ad; + db0a16e9769e8f2fc12c7f839fab269a0056284a697ffd4113a1cf43b5d5bdce + 2d86dead83f5a356e9106bedf908db61f1119f9700260ea9379cc7232184d217 + ad5a3798580a21a9af3a14a20c498e9ba81075c0d4c771481da0b3e6544bb711; + 158fee8ca42e75614739e9007f234fbcd86b0ad8f641a0449b6d9b0f99d1cb4a + 57a4d6f987feb0ade90aa1d81c4f497b3734be301da3e25fe692629db57311f4 + feca63faa55407c1cbe7ba36da4101ed6fc318162d0834ef6ea91095e6fbb38c; + 22f3a1573f9e0553a23e96265e4326fa532d7136863e5b4bc6c99ade3d4eb23c + acdf6e42ad8ca13187eba1532920ba31582b3793b05fa65e9f80c5814b91f4d3 + c9ddac65e7d93033570d39fc200ea11df6f56cf19994e791092cab78342f8793; + c581c7b16c46b484859c6d19eebaf124681aa3be9943307fa4ef095ef8e7e50b + 703dc0420e74227c9351366ef8e98e1e24b48aa989dbb8d0f10471ae5428a601 + f1e437fdbee29a5838d58d6ca0abd51bf3fe4bed82ea86f5e3d2e8effa7dbee9; + 2fbe4f5cb2dab2863e574842cc0b3774e00dcfa63b0db1716c7e916a26fc2e19 + 8f8db63ab59955989497782f16c5816270ef3fbe4ea22f484ddc12ec8f4bdbd6 + c8721ce2f69e7d5d6fc5746fea4185ff8a7d296b99bcc17bbbad3e7036053bcb; + ebdfbafb21fcf5427dbee5f95b53a0b4cb6d7c128b79f4657895f4b0ba518dd6 + 1436140f20d40224baac3a602da83cb254a7e03f052c63c1f3f00f301cc944a1 + f3298d9cfbd5fd3a98e1ecabe8a2aac82b1b54f2f65f09d7cf3bcd9ca8bd2bcf; + 789133bb8048f07dc123f2ca7e20c83988e4bfea6d561ab5aea542db544a1437 + 6d5d52f7265c7a8d2fc4feef99b9dba89eb472f71d8eb5affe900d776e4cf74e + 795de908ed1e3149d3e92fc4d2fb56c47db72b54097702f360c3de4363a1b38c; + 52b6c86db981143082735c6473a86a5da3d2e8cbb8602ebbaf08bf9315fba15f + 46714bfd2c8312fb5744dfe84615ddb93f15360161f2efb1fc39b8b6ad97427d + 9e96a1dd18f2683365cb98a46a9cb8bf49f1766ac86eddec4a87dfa3f83339ce; +} diff --git a/symm/t/idea b/symm/t/idea index c0b928d4..c51e842a 100644 --- a/symm/t/idea +++ b/symm/t/idea @@ -24,3 +24,245 @@ idea { 729a27ed8f5c3e8baf16560d14c90b43 d53fabbf94ff8b5f 1d0cb2af1654820a; 729a27ed8f5c3e8baf16560d14c90b43 df8c6fc637e3dad1 29358cc6c83828ae; } + +idea-cmac { + e4bef260d7bcda163547d348b7551195 + "" + 2a288096bbfd3366; + e77022907dd1dff7dac5c9941d26d0c6 + eb + 2f7fb9948ff504c6; + 14ad568f86edd1dc9268eeee533285a6 + ed810c9b689daaa9060d2d4b6003062365b0a54364c76c16 + d077db9252901d26; + 0f11896c4794846ecfa14a7130c9f137 + 120634c9519848a877ff77bf79192a5b50ade5 + c17895f93dd73a8a; +} + +idea-ccm { + e4bef260d7bcda163547d348b7551195 + e77022 + "" + "" + "" + 42939dba; + 907dd1dff7dac5c9941d26d0c6eb14ad + 568f86 + ed + "" + "" + 3facc6db; + d1dc9268eeee533285a6ed810c9b689d + aaa906 + "" + 0d + 7e + 4f9519dd; + 2d4b6003062365b0a54364c76c160f11 + 896c479484 + 6ecfa14a7130c9f137120634c9519848a877ff77bf79192a + 5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba23408540 + 53683900f166af9bfd8a3e46e63e8e38af27b1c46816b6ae + 5e8bd4980b4efd9c; + 6a6136512061f7080cc07df0591d8fa2 + 1f2dd88374 + d8cde8e160ad10997a21635c6d62c9269029df + 3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e5 + ea20e70bc5af22eece46f5b4adb9148a716a08fe014fd8e603cbad4b05 + df275b1d8b433882; +} + +idea-eax { + e4bef260d7bcda163547d348b7551195 + "" + "" + "" + "" + 2ed1b711b35815fc; + e77022907dd1dff7dac5c9941d26d0c6 + eb + "" + "" + "" + e16c2e8dcbe82476; + 14ad568f86edd1dc9268eeee533285a6 + "" + ed + "" + "" + d71cbbb104ef47b6; + 810c9b689daaa9060d2d4b6003062365 + "" + "" + b0 + 93 + f9fa771344725555; + a54364c76c160f11896c4794846ecfa1 + 4a7130c9f1371206 + 34c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f33 + 7f29549e6b0d27a4ba234085406a6136512061f7080cc07d + cfcb5b76771f439b7e31a9503bc42213efcb50281711c0e0 + e70f4193b0a49031; + f0591d8fa21f2dd88374d8cde8e160ad + 10997a21635c6d + 62c9269029df3e6057acc87638f508046733d9 + ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50 + dfd640ccfb02298e9bdb44464e210bb5039e2fcfdf99a07198b5a41744 + 8100822295ddbb3c; +} + +idea-gcm { + e4bef260d7bcda163547d348b7551195 + "" + "" + "" + "" + b53b4af5791611f9; + e77022907dd1dff7dac5c9941d26d0c6 + eb + "" + "" + "" + 5d33a50146fc1873; + 14ad568f86edd1dc9268eeee533285a6 + "" + ed + "" + "" + 476a48223872d6dc; + 810c9b689daaa9060d2d4b6003062365 + "" + "" + b0 + d7 + e7f3f045a67219ca; + a54364c76c160f11896c4794846ecfa1 + 4a7130c9f1371206 + 34c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f33 + 7f29549e6b0d27a4ba234085406a6136512061f7080cc07d + 35242bf91114f81e19e23a3ac1ccd5a9d133f097e1e32358 + d7871555c86f43c4; + f0591d8fa21f2dd88374d8cde8e160ad + 10997a21 + 635c6d62c9269029df3e60 + 57acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dcea + badb12a7460b5d77826a7f419823376c332f6816280031f04aaffa9b92ed8c83e9 + ca45ffd7a56d9250; + a7b1cc49ae1d50c38201a894476b3f10 + 2b752eb9529533 + 966f27043eb621b7f65b000961040ef2f9b2fc + 5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18a + 8508e77f69eba79e7dd8b644ed31dba2f0eba90d09b1170ec17caf72ee + 6c86db8654126e19; +} + +idea-ocb1 { + e4bef260d7bcda163547d348b7551195 + e77022907dd1dff7 + "" + "" + "" + 6c1f67d06c352235; + dac5c9941d26d0c6eb14ad568f86edd1 + dc9268eeee533285 + a6 + "" + "" + 461d68824249a125; + ed810c9b689daaa9060d2d4b60030623 + 65b0a54364c76c16 + "" + 0f + a4 + f29d06f84026383d; + 11896c4794846ecfa14a7130c9f13712 + 0634c9519848a877 + "" + ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27 + 02d1b52db3743fe74199d2d47c7b9a5b40be540fd3305c63 + 95db9f9e14cc4137; + a4ba234085406a6136512061f7080cc0 + 7df0591d8fa21f2d + d88374d8cde8e160ad10997a21635c6d62c9269029df3e60 + 57acc87638f508046733d9ff61cdbda3b3e9878731ebfedd + 16241a876ecaa1787050ae161dc95e08b3c9f3f32f4c28e6 + 4c3a1cbf28420f74; + 4705e505da1435dceaa7b1cc49ae1d50 + c38201a894476b3f + "" + 102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa4 + fc37976d31a17e5c9184a761ade81acb146791248da7073854564e80e2 + 69afdd038f3f443c; + 50727a9b542cde52ebfda19d0ccc520f + 215eb57bb3a4f3eb + bbb18ac6c95a97a48030370c33d090c54215ab + d6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff6310 + ca23f10e82cad6a83e29296f3040d728e2c19d8a70da3c85bfd6392e83 + 13a82d59cedb63ae; +} + +idea-pmac1 { + e4bef260d7bcda163547d348b7551195 + "" + 487cb8bbd49fdf9f; + e77022907dd1dff7dac5c9941d26d0c6 + eb + 61e71d184211ae2e; + 14ad568f86edd1dc9268eeee533285a6 + ed810c9b689daaa9060d2d4b6003062365b0a54364c76c16 + 2a59b4037636f6e9; + 0f11896c4794846ecfa14a7130c9f137 + 120634c9519848a877ff77bf79192a5b50ade5 + 64b5b29952d302fd; +} + +idea-ocb3 { + e4bef260d7bcda163547d348b7551195 + e77022907dd1 + "" + "" + "" + d4146d9749c5b4cc; + dff7dac5c9941d26d0c6eb14ad568f86 + edd1dc9268ee + ee + "" + "" + 91344823fdca261a; + 533285a6ed810c9b689daaa9060d2d4b + 6003062365b0 + "" + a5 + 32 + bd1e855f2cfab6a4; + 4364c76c160f11896c4794846ecfa14a + 7130c9 + "" + f137120634c9519848a877ff77bf79192a5b50ade5d9cd73 + 9de3e559bcf16005a54f07a11b791f0c87486d260cd04d40 + 0f6c004bce2fdfa4; + 9a3d1f337f29549e6b0d27a4ba234085 + 406a613651 + 2061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10 + 997a21635c6d62c9269029df3e6057acc87638f508046733 + 07d9e965ec0f32d6ba5393c0504a9e274d18fbb31e705f7e + d1f5621c6fa3f2c9; + d9ff61cdbda3b3e9878731ebfedd4705 + e505da1435dc + "" + eaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043e + a51612481f15245dfec7f8e1ffa9bc47788140faac776d8fce971d2d96 + 2030845d5729cf4f; + b621b7f65b000961040ef2f9b2fc5fa4 + 50727a9b542c + de52ebfda19d0ccc520f215eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b9 + cb28e83ecdf27012219f655bf27bb37de417f09f4337a92bfe5feb3da2 + cc56a222f733795e; +} +idea-ocb3-mct { + 16 81bc29159fbaf9aa; + 16 fb5ea26d7558; + 16 1749134c; +} diff --git a/symm/t/mars.local b/symm/t/mars.local new file mode 100644 index 00000000..126fddf9 --- /dev/null +++ b/symm/t/mars.local @@ -0,0 +1,922 @@ +### Local tests for Mars. + +mars-cmac { + 60d7bcda163547d348b75511 + "" + 35a1192271ad4f717fe9e5ce36550ccc; + 95e77022907dd1dff7dac5c9 + 94 + 79d05cda7236e8a9038a3e87d6dd590d; + 1d26d0c6eb14ad568f86edd1 + dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1 + 04093d618ec9a9f929abceba0ea5d6a5; + 37120634c9519848a877ff77 + bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8f + 0436ec24f98dbf64019710d997ca79ad; + a21f2dd88374d8cde8e160ad10997a21635c6d62 + "" + 51be3cd07c56c6f821f8261bbf55fa38; + c9269029df3e6057acc87638f508046733d9ff61 + cd + c29104d9daa7eb4abadd817b6890df83; + bda3b3e9878731ebfedd4705e505da1435dceaa7 + b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b54 + 6b2daa274c101b703e7cca9de8608b13; + 2cde52ebfda19d0ccc520f215eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e2 + de39e39bd3108b76ec6c4c68a923ecfc; + 7fff63102758fe2b + "" + db668c175219b873ce67bfee1bf797dc; + 69ac26afa3349829 + b9 + d8e6cec8197a0d3b02b973e0b8821048; + 4586306fed54154f + 8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42 + 1fef4ac7afbf6a5b2e8c6eb271a6c73c; + f70800df9fcbaca4 + 8b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66 + bdc7b92cd3b6b1f19165fa1452144363; + f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b + "" + baf27c811850b45c6165fa5f28c558ea; + 6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65 + b9 + c838ff7ffa0b020de74cdf1bc6d9cb1b; + aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf3 + 0f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa92 + 3834f582405017c74df2a58f50896bbe; + 1451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e61766 + 9c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb6 + 797407de4940048d366f408567a0b4ca; +} + +mars-ccm { + 60d7bcda163547d348b75511 + 95e77022907dd1dff7dac5 + "" + "" + "" + d9863a89; + c9941d26d0c6eb14ad568f86 + edd1dc9268eeee533285a6 + ed + "" + "" + 291967b1; + 810c9b689daaa9060d2d4b60 + 03062365b0a54364c76c16 + "" + 0f + f7 + b93f6b02; + 11896c4794846ecfa14a7130 + c9f137120634c95198 + 48a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8f + a21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731 + 9828628579a7dd487f473888502c5c84369b7c3a4c760eca290e95d6ecc9f0eeff551a28e55ab8f07a3b3058263e6590 + 232a8e27bf269e09d6ca6691858e03d3; + ebfedd4705e505da1435dcea + a7b1cc49ae1d50c382 + 01a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52 + ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605f + 983ddf84477174e42ff5e4d86e34a4dba2cda48b0d9cc34dca96cae438508ea257ae6e4d0f34e6c38612bc4044d30e3f44550b49eb + aece86043084433dff242601596ec036; + aee2b03fb648e27fff63102758fe2b69ac26afa3 + 349829b94586306fed5415 + "" + "" + "" + c9700d28; + 4f8f28523c03d4de1600157846b710ee72807a22 + 19bfb474fd71d891f24bb6 + 5d + "" + "" + 86ac2560; + 1563259f9eb53b571ea629c54d57dd2d42f70800 + df9fcbaca48b77dba18919 + "" + 6d + ce + 7396d0ff; + 1ebba10b0467cb9fc2712a199e533fa9156308cd + ec3f768281e040a9b9 + a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe83681 + 31115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd4 + 2e78ed36197ee0fbe02aaf850ca07cef75d83137dfa779a043f43ad6207cb71df53b3bc72ec31947217f1131f9a7219f + 38d70bb7304992be2073bd3ded9589ad; + 1e72d7b97e23e6eabdff3bcd211499268878dbf3 + 0f1dad89d4b9b12012 + e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1 + af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16 + 91a4428db21b6870c8bed64235a802123bebc572b852321902ffa4e1f9197eab5a4e2d6e37587f493a77dc78355556ecf4078f6963 + 2ca5ad4c8de48446dacc9ef0f8ed8ac6; + c2e815f422cdf0c8 + e30308be3c31e6bc58c0b7 + "" + "" + "" + e55b1e3d; + cadcb658b970e474 + 79a684b5aefa69a4cd5214 + 7e + "" + "" + 8e9f4277; + d12ca986981a8744 + 98ad0abef8bc4fcb70e27e + "" + 98 + da + 94060c3c; + ef1f0446b42fb144 + d44b6d00f06dc188d4 + 72a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf439 + 66eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb + a845f5b258e7b48dfbf165716b84ab9d44a6fb31ae2db3969ab9236937b52c81e38427414b61004125cd07ee50001947 + 053ae04c909fb9c1202dc16d15d93890; + 824173d7634c0422 + 6f30cbb7f0e4a973a8 + cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f2 + 94b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1f + 7bc1f6ba933f20ea05b7b6eeed69b99dfb31c21c77a46690e151e756c0af9555851d17700b27ac7d1104a4ce197bb4d3e5d596ed37 + 5b81abd7dea2c26dfdb3dd4fbb3679c9; + f6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c8 + 4cef64f6c9b53bf8f957f4 + "" + "" + "" + 5702f7ae; + b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b + 1abf91b0851e5ca605ac84 + 51 + "" + "" + d5c802e3; + 399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41 + cf9a05c7efedef3401539c + "" + 51 + df + bf7584e3; + d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92a + dd9589d1f5c054b2d9 + 83514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d558 + 9bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42 + 332eb9ba36705464ae13b42c953572119f3bd26d623fe066fa9eb42a3aa5222fc7a39367b997e903b8471ded7b4e1250 + b10fea22e3e1c7cbdf334e2e66986200; + fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9 + aea3ccf860b0009740 + 763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3 + aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd6777 + 2efcfbce25279f45598c9d5dff6821a9b6bdea37fc7c376e8a65c0d6182392b15de9832a2477f5c446b3028872892061a213cd7f51 + e44e2d82e160ef2cd7d28cb80fc74194; +} + +mars-eax { + 60d7bcda163547d348b75511 + "" + "" + "" + "" + 783e4c5710aa46926fa54c1810e7e73f; + 95e77022907dd1dff7dac5c9 + 94 + "" + "" + "" + 1f777486cbacb84834939cf4312ba37f; + 1d26d0c6eb14ad568f86edd1 + "" + dc + "" + "" + ea4ee101b3dfc447826294eb9e188f93; + 9268eeee533285a6ed810c9b + "" + "" + 68 + 32 + 36ad1e9dd22bc536eaf6e1bf4148b92c; + 9daaa9060d2d4b6003062365 + b0a54364c76c160f11896c4794846ecf + a14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a61 + 36512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f50804 + a2b79ebe3a643e16a26496a833169c430350296feff84ab5e97a837f27c1cebf042c077d8ea23697c1101fcd3880025e + 3e081ad4715f6b2ccf59ac6cbee3ecbf; + 6733d9ff61cdbda3b3e98787 + 31ebfedd4705e505da1435dceaa7b1 + cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450 + 727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b9 + e32192ca15a8b60348fbcad6bed31fec7d8930fb015efea33f827a691a245be1b056f237da85e63dd7f6948a583c5040b24eb76747 + c69cdf6b68ff0b95fd49073f69b24673; + 3bf4f2aad2605faee2b03fb648e27fff63102758 + "" + "" + "" + "" + 8197dfbcc4259667affb2610283f7cb5; + fe2b69ac26afa3349829b94586306fed54154f8f + 28 + "" + "" + "" + 4365d2d730280b57ebdd628d574db279; + 523c03d4de1600157846b710ee72807a2219bfb4 + "" + 74 + "" + "" + 90f8bb6ae36b77e86acd862d626e3e8b; + fd71d891f24bb65d1563259f9eb53b571ea629c5 + "" + "" + 4d + 4d + e0c975ce580afac6215a31f89ed849f5; + 57dd2d42f70800df9fcbaca48b77dba189196d1e + bba10b0467cb9fc2712a199e533fa915 + 6308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d + 95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca33852 + 68cd20e274b1dfc8045c4f1a2a862ae38adaf6f1b4d37a869e1ca4dce62cffab0e767e21b7980a7a6923a4e6036e261f + ab0fc228a30f96fc6af0af7ed3b2ca23; + 7ef19b09c063c46f88de9fd41e72d7b97e23e6ea + bdff3bcd211499268878dbf30f1dad + 89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aeb + fa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d + 2d5f33737604edbff4256e1803d85fdf97b1d11755a7c54907279c926103ad6dfcd2a49bc8f09692af0225e58727302883110a1d9e + 66d2add5b20b0083fe707359e14b9a81; + 264a7f16cb16c2e8 + "" + "" + "" + "" + bfd46275d139ade04b23701a58f03996; + 15f422cdf0c8e303 + 08 + "" + "" + "" + 70b1aefbf33858867e95f8420409cc5c; + be3c31e6bc58c0b7 + "" + ca + "" + "" + 06ed7dfc19e244619a78291ebfe53e1e; + dcb658b970e47479 + "" + "" + a6 + b3 + 50a2cbdf827bdd413fc402b1bd4d3cad; + 84b5aefa69a4cd52 + 147ed12ca986981a874498ad0abef8bc + 4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9 + eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851 + 1717ca0fe9a9f844e7b875383fffb728907e4381ca81aaad7d07ae4559463a25e3eb4eddc2c1eb47ac009050404e125a + 54681d8a74c5240d91fedda335ba0106; + bc2810d858cbbc84 + 24d126b807e6daa089c3f9099c5ffb + 824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3f + b90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b + b49998808ffe0713f231dc44d5fefd7b091d037fa88a0b00fa7df49a9cb715fa11272ad859a1b6bcd40fa4a618d4b9694a98800fe1 + cfb2cf5bd57a0bd2e0b6e4766c85ee66; + 9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458 + "" + "" + "" + "" + c182f7ff71663492c075606138691990; + cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a + 3e + "" + "" + "" + bfd6579cd96ad44cd5202593235be036; + 8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605 + "" + ac + "" + "" + b0aa4fd770b15ab6cf76338e9e4ffcc9; + 8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529 + "" + "" + ee + 1e + d1aa1cfbf63991b5a87719a436f3bc15; + 41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a + 5718fd25014107c8e7d715a92add9589 + d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a3 + 32ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d + 6c1092bfaaba31b04c5ce196bd217368bbcb33fabbee09d16cc36d6047594e2f33f6241828d17230e69561355af84d2b + 9adaf12e17b54bb121e92f5262a03d46; + 2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e5188 + 1e99027b8ab9aea3ccf860b0009740 + 763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3 + aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd6777 + 64f2ee469fb1577675427113e478b43ab8915dfc5a3370b0b55dadd51f1415083831183748bbbd393ee54171fa12a112addea5bffd + 4172000e1d04402689bffffdf46cabac; +} + +mars-gcm { + 60d7bcda163547d348b75511 + "" + "" + "" + "" + ebf333475ccfd01e22434b02b7356886; + 95e77022907dd1dff7dac5c9 + 94 + "" + "" + "" + 1f643ac59e0fe29a4c1a84833c1093b9; + 1d26d0c6eb14ad568f86edd1 + "" + dc + "" + "" + e8ed5ca386836f0fde3d8def53764182; + 9268eeee533285a6ed810c9b + "" + "" + 68 + c6 + 0a84b3ea1725580f6ff197fc09ad1d97; + 9daaa9060d2d4b6003062365 + b0a54364c76c160f11896c4794846ecf + a14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a61 + 36512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f50804 + 22ebe7296754751f308114594df1ce2c029a959eb46639dda878d75cc411f58924dd49d15b515cb32c987716b9668fff + 9a65ff41da556c3b4ea0154dbc6a7432; + 6733d9ff61cdbda3b3e98787 + 31ebfedd4705e505da1435dc + eaa7b1cc49ae1d50c38201a894476b3f102b75 + 2eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97 + 5ac307a7ba0e8c3f15b3da71b2dbe231914d92040e6099060e12312f940f512a4bea4f140ffc99e37cd4c004fe70fd9afead2070b93e171944 + 3e3a39a40c14cf4455054df3dc812412; + a48030370c33d090c54215ab + d6b3ad54efc9a38378c5b93bf4f2aa + d2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de16 + 00157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189 + 0c0dc2d9d390c165b844a4fe302c9468dd61b989ec85e415c2e66a02c6a9e88e6c4b29b59526b3bba15ac8c7c773fad8cd346313d5 + b66ce563af3c5adeb147f05f2a1332a7; + 196d1ebba10b0467cb9fc2712a199e533fa91563 + "" + "" + "" + "" + a3752b6bc192c30a8b4a33090b82c8f4; + 08cdec3f768281e040a9b9a222bd689aef66f530 + 6c + "" + "" + "" + 2d7f085e88e212c1d5a7470222846f6d; + eb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa + "" + 6a + "" + "" + afd0596615ac5995f94a4c4933d7bc2b; + 5cfb0bad7d95214ade49cb3b6f5fe8368131115c + "" + "" + 03 + ac + 06c5e4184cedd818df6808aed1cbaca3; + 7ba323fe1dc8151784873f0eb5b647da6794c18b + 5337685a96ed65b9aca338527ef19b09 + c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d2 + 2bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d07983 + 41ed7b09be9ff9174abf78851ec6b7dd1de6abae054b330e761068fcb38c10e658d4a4dcccf87c9bd972a7c3736681e7 + 87c051ef30fb9d6b610ac3d8b367d190; + 91805da08da3aefc5f8584b7c5e617669c0f16e3 + 9815d4e9cfce3ed1ecdf3d26 + 4a7f16cb16c2e815f422cdf0c8e30308be3c31 + e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00 + f08e36ab5ed57342834832ae777155f3b98a75495279de1d647d6cbe54143a9ccd11a1394c37aee68c4214deb21134425a11084387c60b3af4 + 4a3532e7462571f4c0aa720877fcc127; + f06dc188d472a784e0c6f21195a3b9f4ae985511 + 265febd11c164720eef9eb1c8dd0b0 + 0951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851 + bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff66 + 0dea7dfec76fd70330daafa91a42de22cb7d9ccb8f762fb36eeb5cacf96cad8a5972e163c42f0ccffceab82352f7b357614c058b2f + 8e46584fadfee6bf54b6b3df1127e528; + 9c732b58db8f48af + "" + "" + "" + "" + 97b6cfc2d51f18dbfb036aead20cf7c9; + 65f7cc9e3fb90e17 + 21 + "" + "" + "" + e660c51ce4935fb6b0568b9da21fd6bc; + b730374ffc9bc597 + "" + f5 + "" + "" + 029a8fbbcffd6a6657ea08e6f8563c5c; + 6ccbb2f294b38766 + "" + "" + fc + 73 + 8a51e96b7e49dd61bf505d6be05880c1; + 69f6a9f2c0945ffd + 505003cc0cae9ce021a5f1fa4ffa9154 + 4485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd40 + 9b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70 + 51af1a674261ce3b602216b7be5490dc29b5c0fc13111ef312aee59aa415455eb45ecb08971640295ee6083d336852ff + 033c89302140a07d7ec18495ac6e04de; + e04c091d205cdad9 + e9a79b1abf91b0851e5ca605 + ac8451399587011677508a15dde524af3e2bee + 0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718 + 1322a51e98047b8ab460b5862ecb72506d86347ff23da7c246c7412e66f778c44fcac56086f6233cc65342b25825c27447162c75c4f4d47e77 + d1c84ad7d023b7339eeb10cf9d4a54b0; + fd25014107c8e7d7 + 15a92add9589d1f5c054b2d9835146 + 05ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5 + d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b66 + 7d49e4c21966171b11dcd2557bc759735b6a0f8883869a032ff7e3b7300f6c177a17c78de29b7dd1fb60dcd83df08d94b4f7b203fa + 9e558cfae2396ef731781539964cb64f; + 9ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3cc + "" + "" + "" + "" + d7edfedbfaaa00b83910524a6a72a0bd; + f860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c + 1b + "" + "" + "" + 9b47dca7222907d7728d60047341be6b; + 9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a30 + "" + 8b + "" + "" + 4d7ff706428aed21fed40ba423e497f6; + a60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a17 + "" + "" + 0b + ed + 513db06c53e14e17a0a6a2358c63eb84; + 66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861 + a8b33779f09e7a10fc02a8f48afa3080 + ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac27311 + 7b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c88088476892114 + 1cabcdd7bd2c878d0d509527aba73014be8fda187aad0fa6171cdf7b40611f6e0436653ff03bdc3540fc240fbf2edf11 + 4747f36bac04dfc0d594803a8b5f7393; + 50ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785f + e426a5a0e80f678d40414784 + 2941feeffdc2eb44dc8c0d5e8f444f7f4e0c89 + 3959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf8556b7aa7 + 83be0a213ffe127c49ec5352ec0f5542abda27387079f4e8f6e056187eb8e7afe34ef415383f54eeb5332137ca5407e3bb19019796a375286c + 03d0ffe3b26614eb375f0f9043d69cfa; + 76945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8 + f08ce7cee4758a386a9943e97dedfb + e61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98 + edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bd + 9f02629363a56a6e8067f76d0df265f5d1d4774c129186fd96e0826e4d5a6fd643b6fc7e484caa72575f7774f8d7d55529c816b3a8 + 77d7548dfeed0ca41810c69586ef999d; +} + +mars-ocb1 { + 60d7bcda163547d348b75511 + 95e77022907dd1dff7dac5c9941d26d0 + "" + "" + "" + 4653e79c83c9692f680b6ab67aa4cb1c; + c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d + 2d + "" + "" + 9cf228b3a0a873d910ef08325178c9ce; + 4b6003062365b0a54364c76c + 160f11896c4794846ecfa14a7130c9f1 + "" + 37 + 7f + 3194ce1f7b3c055b5c465e9449713d73; + 120634c9519848a877ff77bf + 79192a5b50ade5d9cd739a3d1f337f29 + "" + 549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c926 + da19eb03799876ac0c7f25bbb54e051149623d839822c5305b2348306fb687a95debfb6d8463b8f61eff55879a8e4854 + c9315ab551796c3230de8d1b783e41c6; + 9029df3e6057acc87638f508 + 046733d9ff61cdbda3b3e9878731ebfe + dd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040e + f2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215 + e6fffaeff62574ca11871e98539b5d6252724476ceaf2e6f7649e25df4c7fa2d1168bc6913bfcabbeb65cc7673d64445 + aba7309b9f99d4d595029cb68eb9dfef; + abd6b3ad54efc9a38378c5b9 + 3bf4f2aad2605faee2b03fb648e27fff + "" + 63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb6 + 41d2c5f2747177da8fb403142b15976849d6092a1f30a00a7dd86dfeae5e9a4d37a2b63ab07ee4ef461bb0c5a0ccce42767d08bf87 + a5990263e713d60c619a4c8e15b6b3c4; + 5d1563259f9eb53b571ea629 + c54d57dd2d42f70800df9fcbaca48b77 + dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f530 + 6ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc815178487 + 996f3de0c448f6bcc7a05966caf6b55b9a6e89038b7b1dcf0e227940a481c7d01a8deb9ab18c66e6e40f77673084abf2237348d737 + 12639c6038c9de5dac44e56672cb55aa; + 3f0eb5b647da6794c18b5337685a96ed65b9aca3 + 38527ef19b09c063c46f88de9fd41e72 + "" + "" + "" + 2a302865877be6802bf265563679f4a6; + d7b97e23e6eabdff3bcd211499268878dbf30f1d + ad89d4b9b12012e4713df46795630e79 + 52 + "" + "" + e504301acfb3dd72388b857ee7030835; + d22bb02d7100b8b649377d20a8f083455b663e4e + e1315f3c8f2aebfa921451dcd1af5813 + "" + b7 + ae + e2242b2d76d0f58177d422c14007837b; + 0d30ce2f1fef6ef315d0798391805da08da3aefc + 5f8584b7c5e617669c0f16e39815d4e9 + "" + cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4 + 289ee6d05f1e2afadef55a9be57142c9434db665577e5e471466dcf0cd8dcee27b8337966c5f1a45a88f87801fc4ec61 + de6956f5723d140cb3147978cdaaded2; + cd52147ed12ca986981a874498ad0abef8bc4fcb + 70e27e98ef1f0446b42fb144d44b6d00 + f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed0045633185 + 4bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3 + 6887543c971afe587132ed940556ec6275f8e92d4f94bcc8f31ed297ebaa6757c4353fdc1f6bdb1a870c22336f825a96 + abce9a9e9c6f5d09e99c93d7eadfede3; + f9099c5ffb824173d7634c04226f30cbb7f0e4a9 + 73a8cd190107314717a77456f3ff669c + "" + 732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1 + f449b1339ac9985a1c4b342d1b0a5c41f15b8b2aca90c12846c792ae42057b3fd7b41111c8db756adf5a2ef5e1546e57fa0243cfb7 + ba66681acccec14ef865b02f3c39b3f6; + fa4ffa91544485f1a1258b2b9b8f0911e32d65cc + 1770a18cbfe6effd1ff6778554acf127 + 0485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf4 + 3e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a + 7e1008b868fc1e9839963cd536e425796a5a83fbabd727f72bdf86fef8cf16929a5d491a4657a4228a19e366a213f820cda50268b2 + 3f0cd60dee1bf4bedd8415232e0e5a2f; + 15dde524af3e2bee + 0646541a42c2ecccb44d65bad397abfa + "" + "" + "" + 158bc7dac7095b407e95a345ec6362d3; + f529ee41cf9a05c7 + efedef3401539c51d2a90bbf7f1bfc33 + 8a + "" + "" + 8bef95789b98fffc2e3a3324237b03c4; + b0ef5746ea8fdccc + d213e33f7e8a5718fd25014107c8e7d7 + "" + 15 + bd + a88cd72e0e1e676c5c011dcbc14d2e46; + a92add9589d1f5c0 + 54b2d983514605ec590294a319b98020 + "" + 68a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e + 6ed48f6abe15219da489442825e579452118ad3fef19d76292398eaea3a27d2cf358a5a1dfc1810c68b5e17db646d4d3 + b19f3b616690535f642ae58f4263880c; + 6b7ea2725cb2dac0 + 7ecde95759ac46fee6dda7abc8ad68da + ac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9ae + a3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1 + f5c8dd655912fff44348c17cc0a0178fc55bbb12f4af3a017bc8db8b27c168d1feb19bcdd00b8f738adb541425412da2 + 820fbdee601293312a0756571cdd2389; + f6a7a3aa7e740da9 + 67828e3604b35b15ffaa6c36800d9645 + "" + 563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c39 + 201b87f6e406e13217b302fb759395dc0aa43b22b175472f45de5349ad46fd04c6fe85eb5c553432dd49fc279f668562f705ca3aa3 + f7b7990d4d35c703d03b18b009bd6a6c; + 73accd56f6f24e33 + 958b8c2e2352fd61e4fa8fec816ac861 + a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc8 + 75fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f + 1bc1cc2a9d971ffd42de07dfe98a00df3e83baf24c8a7b658eaaad1b61726d6b9aa527fadebb284414e9d75eadd23274710de7818f + 294968c6ea337be16fa4b02cdfa33e50; + 9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab6 + 1f813e28a1397a7974a1d7f4220c785f + "" + "" + "" + 91db1563a8a1d0f60253be719e1e41f1; + e426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc2 + 3a7bb40e7e0013e5150686d2301b43a1 + 5a + "" + "" + 83e94ddd60fb2b811905035945907c5d; + 84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf8556b7aa776 + 945948d1b8834df2196c92ec1718dcde + "" + ee + b2 + 0d56aa6e43ad24239efcfcd726927fc1; + 0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e73 + 7882cd09c2b9a80f34c0fde11c2481b1 + "" + 1fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1ccc + b8b85de994a54ef5dbcbd85f5eaa88e2b2464262a53859300232029741b167876b6d3195c95957d5600e31de5f275da6 + e69278334c8133c3710564526e2016f0; + ada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d9 + 21056b7de74fc9a9b37154ce6c0b3961 + 79d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cbcf96523d + 4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59e + 9e1e7295f6bb0cf520a77dc6bf4cae9411c79bf4d9e6a2a862efd982f4525bdd026b7ce5bb28b46bdf4bc4eb3e8e9675 + d5ca1cd9e51f5441912d15626930b798; + d034a867642d25d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a + 22d9fd881519165eb9d85197a21cc34a + "" + c0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca + 33c0fb24bcc9948f79e7257d8816767fd83a862643e0e31b1ecde6dfc39523dbb29b396435eae70c7658cbb9442c457805713c45da + b0b7b3760231dd8ddd9a6378e27fadc0; + 34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f + 938f6daafbd656445a09898eaa96ffc3 + d1d2e31e4e34c94b8bfae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538 + e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a95 + da25756b3f6d874af5fc62eb4d23153e0f42f476f6ef83622e6b704eac2b1c0ffe419780e789c457c51fddfda8c999b9a4eba0ae59 + 8c06ff6ecbcc83696b7a3ceb00819fef; +} + +mars-pmac1 { + 60d7bcda163547d348b75511 + "" + 88349068f0361feb5ab861422204a1fb; + 95e77022907dd1dff7dac5c9 + 94 + 68e53c106eac08332168b9710686bde0; + 1d26d0c6eb14ad568f86edd1 + dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1 + e73b3d7d64f57c88e3d08c79531304db; + 37120634c9519848a877ff77 + bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8f + 155e94d935999190f3c4707830a1627b; + a21f2dd88374d8cde8e160ad10997a21635c6d62 + "" + 25767cba62b028dc2b28890f20b71457; + c9269029df3e6057acc87638f508046733d9ff61 + cd + 8e847f813725a45c86f09bbdf9d3984f; + bda3b3e9878731ebfedd4705e505da1435dceaa7 + b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b54 + 0f6d60ece48580fae8d7914ab7194ccd; + 2cde52ebfda19d0ccc520f215eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e2 + 922c357cc72223d59ef79018aa0fce6d; + 7fff63102758fe2b + "" + 0b46ed47aa8b8d1c15b9a1be5116955a; + 69ac26afa3349829 + b9 + 779d971e639e3f8c5e8d280d78a56a14; + 4586306fed54154f + 8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42 + 9594bd5550eddba1050516976565ee32; + f70800df9fcbaca4 + 8b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66 + 3f3100f026a9b5c53df1ef563f2e2b96; + f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b + "" + a9fdd55b4c5ff6687cd49667d60d525e; + 6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65 + b9 + 09210b235e15e9984f6d728f4d266cc3; + aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf3 + 0f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa92 + 1ea465d576f919265add525cc88c6cca; + 1451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e61766 + 9c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb6 + b4e1b487ca7856e1a27ae343a761962f; +} + +mars-ocb3 { + 60d7bcda163547d348b75511 + 95e77022907dd1dff7dac5c9941d + "" + "" + "" + 7c296d4449e64315d2b9f9ba0c3ff7d1; + 26d0c6eb14ad568f86edd1dc + 9268eeee533285a6ed810c9b689d + aa + "" + "" + b430fac783a66cc2daed259760916412; + a9060d2d4b6003062365b0a5 + 4364c76c160f11896c4794846ecf + "" + a1 + 67 + 06f7540f39167c5adfddad27cf702a2c; + 4a7130c9f137120634c95198 + 48a877ff77bf79192a5b50 + "" + ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160 + 871488d35db8121121e6c850c22cf29166fe1e351ce6f6027053f625dae6bded20dff82b546f8ba0806af4a9df2e3cd3 + 1cd5f303f4b515ea7c331533b41f4ac7; + ad10997a21635c6d62c92690 + 29df3e6057acc87638f5080467 + 33d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb952953396 + 6f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6 + 04aecdbb5ea1f384759cb21f922d4a5e5f41759933e7e12a46761a0bb58e8b13100338f8ac4f5d71a564d51d2e7ecefc + 0fdac739fa9705100fb282f9c9c99668; + c95a97a48030370c33d090c5 + 4215abd6b3ad54efc9a38378c5b9 + "" + 3bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710 + ecec35b67e05827d1c60b59197ddec40a4afc502e7b22194c710f2d5bb806fca221d81abdce4c507e02f65b5cca4e43f86f5f76f5f + 4eba3f34ab847bcb7fc65d5b06406cec; + ee72807a2219bfb474fd71d8 + 91f24bb65d1563259f9eb53b571e + a629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cd + ec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f + ff28ac43e2c855d679ee89f7f8d4107c8a1c7c20a4f03b59544adaedd185a4e3a5a37ca45dc55e11df1cdaa7a374850225bffc3c26 + 2da2a1575b5dc344c32a8b2a0b4c3dd8; + 5fe8368131115c037ba323fe1dc8151784873f0e + b5b647da6794c18b5337685a96ed + "" + "" + "" + f940a9debe160996da1f147aafcc566a; + 65b9aca338527ef19b09c063c46f88de9fd41e72 + d7b97e23e6eabdff3bcd21149926 + 88 + "" + "" + 92001d0836b97d87051c1f7d9d09f202; + 78dbf30f1dad89d4b9b12012e4713df46795630e + 7952d22bb02d7100b8b649377d20 + "" + a8 + 74 + 67e9a575f013c2692d295c6103d0d0cf; + f083455b663e4ee1315f3c8f2aebfa921451dcd1 + af5813b70d30ce2f1fef6e + "" + f315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cd + 0a797f00e405100dadb704f4ff09a0a4a8cbe6cd46a0b27529f64b9c56f9d70e688fbe551fa24eb5d3609185b4bdceed + b672df8063219f6c88308bdd3a3ad799; + f0c8e30308be3c31e6bc58c0b7cadcb658b970e4 + 7479a684b5aefa69a4cd52147e + d12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4 + ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc3990844 + badad19dc5594c261a3c5f532b3dcfadfbb81fc53ed47dc2ed8327af497dd998714d1a882310f27ff3cb2c59c024d6e6 + e4b3b99d7d2e296fb0c0de581f1b5fe9; + 5608fe95e81c2533e31c9c1a9851bc2810d858cb + bc8424d126b807e6daa089c3f909 + "" + 9c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b73037 + 21a942eb29d65d2fbf4807ccbb084336916f1003941785547a5346c7eab40931819df2d8caa2549e942e1d09b84b260c7a0dfc0a10 + 672ef4305dcce1cfe09539670b14a261; + 4ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0 + 945ffd505003cc0cae9ce021a5f1 + fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4 + c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8de + 2d0975faff0cd18b98e72bd93765dd3abd35cc4e3cfeb0b6cac1e15e9ed12b4aa038f51cc89b3576ff38a268be71215c4b01dcd552 + b5237448fba31d61ebda5eeac052d5d6; + b9bd205b70e04c09 + 1d205cdad9e9a79b1abf91b0851e + "" + "" + "" + 20c493b7bdf626905c987fb7bf10d8f7; + 5ca605ac84513995 + 87011677508a15dde524af3e2bee + 06 + "" + "" + fa2df8b2eaad48b6bdf3c9bad2938049; + 46541a42c2ecccb4 + 4d65bad397abfaf529ee41cf9a05 + "" + c7 + 75 + 435dd63a2ce8c8458535cd09b20f8d3a; + efedef3401539c51 + d2a90bbf7f1bfc338ab0ef + "" + 5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068 + 64e098d90cbf96bc76262ab532cc962b17fa5c87938daba74d1af81bac2132abb0ff7c47ce79b02b4d6c863ef802d79b + f9732cb1c9f81e4e2a18bc027bb54a19; + a9f891bc5ba5afab + f8c3122d12d7ff3c41122d70d1 + 7d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad + 68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8a + bd7f51b29f6c6f31d1be0eb43533bf93f1b32117242de5011d5e8b25fbb5692531fd3a6c9b48fad09bc80a142ff50ee1 + 86ebc023b905ca6caa36f50a8e18843d; + b9aea3ccf860b000 + 9740763d96836c5f87b95460938d + "" + e1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d964556 + fe4fa4d02555e61c0bd04dff129a4d6936fb1f73d65dd7cd97bb33cb2367ad3cd6e837306ce8bb8f7ae139034d288069d9b25e8c60 + ca2f4b45a793978f9bf62457f035ac75; + 3a308ba600768175 + 23bd2abf1261b089d8f23a9c2835 + 076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e23 + 52fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799d + b15d10be578b00205857262c9108b92645914a0824925535feb7486fb53037fb93d5ff7d77acede5ddf9ece2422636baa4817f4ebb + adff289af064bd7145e742df30acc5fd; + c875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9 + f81d14517ffae475f6b94a43a67b + "" + "" + "" + 0742d3aab5b5f4338953a42eff9de1e4; + 3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac197606 + 3e113ab61f813e28a1397a7974a1 + d7 + "" + "" + 9960763f7362f798c6ca3adf09317bd1; + f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c89 + 3959b74dc23a7bb40e7e0013e515 + "" + 06 + 2d + 1896462db7d41cf1dfc0e73f56e35e49; + 86d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab + 6cf8556b7aa776945948d1 + "" + b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e + 6a517fb1eddc5a9ffcf4b4dcae0c9d2e2f8f70b843e480d9b86d71fdbeebacd5a135f08de14ed70906ccbc4f6107b425 + e699532063bc347b5273ab6c9aa5f8a7; + 737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad + 5b04140d98edabe08485290a4d + 87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359 + f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bac + 8908a7b2b68ebc9659feb4a31163481275f0db4182b7051a9a50e9697f8115ff79368964e9661b2e2db5d2a4c86b5a23 + 33756a80721be9f1105c7afd703e21a0; + f6f9fd3f821330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d + 73d192ee53b3f3ebd66ddd98cedb + "" + e88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb43392 + cdcec7225d6eb19a12720cc24c2a672559618debfdf0ee0d0b350e2701a69124f28d1b76b322cecdadbc67e99342c59dabd11fbf23 + fb30f854d45a706e84616a756a52e711; + 2a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b5 + 4fd9d70c70e117bf1cae71b3a56f + 0e7d839ea59cc783443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597 + a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae64825ecd75a66d88eedb969ffe0 + 98463b6aa0363435ef5f9a71e67406202f51153781195a36bf467b301bf4a676c5af0b7011e15f1ecff79112847529137666ffe910 + 684543c8dbf9b01aee18f5eba0153a24; +} + +mars-ocb3-mct { + 56 3ba8a3d94c3f67e9cef8cf2142b367f7; + 52 f743099826d0e38c48faf27d3edd5b22; + 48 4345a17ed61d2a7b9289f0e12e4350f5; + 44 ef3ad940f5e754a02317f3f1c489028c; + 40 c618d5f97d8913f90a91caed561346c7; + 36 96249ddf7bd91b1df2e2aed3c09bd194; + 32 1f789304aff2376bf2feba8aa9191a05; + 28 7a339727e025fcf65c08152217b95583; + 24 d4d38f1f399005a03a185887fbcc6737; + 20 45e7020dbfdd5f6d31cb441096faf69c; + 16 6b5c2f90abb45cda3622baa74d486f02; + 56 15a0597529ff0ec495e2abc1; + 52 fbd7bfc60b66a65582e96109; + 48 ae651ff80d12c1940539ae3e; + 44 35db8939f38ed596f9940968; + 40 fc4127740b0b0b7c07d2cf62; + 36 282eec1a27cf55e9cda791b1; + 32 95f745dd397a29d2dbcca030; + 28 6935deaa6bc7da04dc7ab3e9; + 24 f46ff7af02ea94fa45404e09; + 20 2f41619c9f36bc9ed459d3b9; + 16 c02f5b63d1ccbe71e928b16f; + 56 05f4e466ef576d08; + 52 b260ce024131b9ba; + 48 ad7f2b73670c5238; + 44 00a12cf14f6300bb; + 40 f0bfc04f2ea1275a; + 36 48585bf1735225ea; + 32 838abfef38920bee; + 28 fe4f81e7b258e614; + 24 b1791137318f5946; + 20 d67d45622c856251; + 16 f34b97c87f3e6823; +} diff --git a/symm/t/modes/blowfish-cbc.regress b/symm/t/modes/blowfish-cbc.regress new file mode 100644 index 00000000..85c0c05f Binary files /dev/null and b/symm/t/modes/blowfish-cbc.regress differ diff --git a/symm/t/modes/blowfish-cfb.regress b/symm/t/modes/blowfish-cfb.regress new file mode 100644 index 00000000..204cba06 Binary files /dev/null and b/symm/t/modes/blowfish-cfb.regress differ diff --git a/symm/t/modes/blowfish-counter.regress b/symm/t/modes/blowfish-counter.regress new file mode 100644 index 00000000..41591eeb Binary files /dev/null and b/symm/t/modes/blowfish-counter.regress differ diff --git a/symm/t/modes/blowfish-ecb.regress b/symm/t/modes/blowfish-ecb.regress new file mode 100644 index 00000000..293b77da Binary files /dev/null and b/symm/t/modes/blowfish-ecb.regress differ diff --git a/symm/t/modes/blowfish-ofb.regress b/symm/t/modes/blowfish-ofb.regress new file mode 100644 index 00000000..1b37899d Binary files /dev/null and b/symm/t/modes/blowfish-ofb.regress differ diff --git a/symm/t/modes/cast128-cbc.regress b/symm/t/modes/cast128-cbc.regress new file mode 100644 index 00000000..f0942ad5 Binary files /dev/null and b/symm/t/modes/cast128-cbc.regress differ diff --git a/symm/t/modes/cast128-cfb.regress b/symm/t/modes/cast128-cfb.regress new file mode 100644 index 00000000..1c859ebd Binary files /dev/null and b/symm/t/modes/cast128-cfb.regress differ diff --git a/symm/t/modes/cast128-counter.regress b/symm/t/modes/cast128-counter.regress new file mode 100644 index 00000000..25cc1169 Binary files /dev/null and b/symm/t/modes/cast128-counter.regress differ diff --git a/symm/t/modes/cast128-ecb.regress b/symm/t/modes/cast128-ecb.regress new file mode 100644 index 00000000..30dda77c Binary files /dev/null and b/symm/t/modes/cast128-ecb.regress differ diff --git a/symm/t/modes/cast128-ofb.regress b/symm/t/modes/cast128-ofb.regress new file mode 100644 index 00000000..c1b5ab83 Binary files /dev/null and b/symm/t/modes/cast128-ofb.regress differ diff --git a/symm/t/modes/cast256-cbc.regress b/symm/t/modes/cast256-cbc.regress new file mode 100644 index 00000000..c81b3435 Binary files /dev/null and b/symm/t/modes/cast256-cbc.regress differ diff --git a/symm/t/modes/cast256-cfb.regress b/symm/t/modes/cast256-cfb.regress new file mode 100644 index 00000000..15cace7c Binary files /dev/null and b/symm/t/modes/cast256-cfb.regress differ diff --git a/symm/t/modes/cast256-counter.regress b/symm/t/modes/cast256-counter.regress new file mode 100644 index 00000000..d3e49476 Binary files /dev/null and b/symm/t/modes/cast256-counter.regress differ diff --git a/symm/t/modes/cast256-ecb.regress b/symm/t/modes/cast256-ecb.regress new file mode 100644 index 00000000..b80c11bd Binary files /dev/null and b/symm/t/modes/cast256-ecb.regress differ diff --git a/symm/t/modes/cast256-ofb.regress b/symm/t/modes/cast256-ofb.regress new file mode 100644 index 00000000..947bee35 Binary files /dev/null and b/symm/t/modes/cast256-ofb.regress differ diff --git a/symm/t/modes/des-cbc.regress b/symm/t/modes/des-cbc.regress new file mode 100644 index 00000000..c423fb2d Binary files /dev/null and b/symm/t/modes/des-cbc.regress differ diff --git a/symm/t/modes/des-cfb.regress b/symm/t/modes/des-cfb.regress new file mode 100644 index 00000000..918db620 Binary files /dev/null and b/symm/t/modes/des-cfb.regress differ diff --git a/symm/t/modes/des-counter.regress b/symm/t/modes/des-counter.regress new file mode 100644 index 00000000..47eefc19 Binary files /dev/null and b/symm/t/modes/des-counter.regress differ diff --git a/symm/t/modes/des-ecb.regress b/symm/t/modes/des-ecb.regress new file mode 100644 index 00000000..412681ea Binary files /dev/null and b/symm/t/modes/des-ecb.regress differ diff --git a/symm/t/modes/des-ofb.regress b/symm/t/modes/des-ofb.regress new file mode 100644 index 00000000..72ae042d Binary files /dev/null and b/symm/t/modes/des-ofb.regress differ diff --git a/symm/t/modes/des3-cbc.regress b/symm/t/modes/des3-cbc.regress new file mode 100644 index 00000000..012065ae Binary files /dev/null and b/symm/t/modes/des3-cbc.regress differ diff --git a/symm/t/modes/des3-cfb.regress b/symm/t/modes/des3-cfb.regress new file mode 100644 index 00000000..c225f471 Binary files /dev/null and b/symm/t/modes/des3-cfb.regress differ diff --git a/symm/t/modes/des3-counter.regress b/symm/t/modes/des3-counter.regress new file mode 100644 index 00000000..05a7e4d7 Binary files /dev/null and b/symm/t/modes/des3-counter.regress differ diff --git a/symm/t/modes/des3-ecb.regress b/symm/t/modes/des3-ecb.regress new file mode 100644 index 00000000..47b26cee Binary files /dev/null and b/symm/t/modes/des3-ecb.regress differ diff --git a/symm/t/modes/des3-ofb.regress b/symm/t/modes/des3-ofb.regress new file mode 100644 index 00000000..febfc6cc Binary files /dev/null and b/symm/t/modes/des3-ofb.regress differ diff --git a/symm/t/modes/desx-cbc.regress b/symm/t/modes/desx-cbc.regress new file mode 100644 index 00000000..253251d0 Binary files /dev/null and b/symm/t/modes/desx-cbc.regress differ diff --git a/symm/t/modes/desx-cfb.regress b/symm/t/modes/desx-cfb.regress new file mode 100644 index 00000000..83d2aa01 Binary files /dev/null and b/symm/t/modes/desx-cfb.regress differ diff --git a/symm/t/modes/desx-counter.regress b/symm/t/modes/desx-counter.regress new file mode 100644 index 00000000..a0174648 Binary files /dev/null and b/symm/t/modes/desx-counter.regress differ diff --git a/symm/t/modes/desx-ecb.regress b/symm/t/modes/desx-ecb.regress new file mode 100644 index 00000000..bd32a6e3 Binary files /dev/null and b/symm/t/modes/desx-ecb.regress differ diff --git a/symm/t/modes/desx-ofb.regress b/symm/t/modes/desx-ofb.regress new file mode 100644 index 00000000..f6e1a8b4 Binary files /dev/null and b/symm/t/modes/desx-ofb.regress differ diff --git a/symm/t/modes/has160-mgf.regress b/symm/t/modes/has160-mgf.regress new file mode 100644 index 00000000..516a4750 Binary files /dev/null and b/symm/t/modes/has160-mgf.regress differ diff --git a/symm/t/modes/idea-cbc.regress b/symm/t/modes/idea-cbc.regress new file mode 100644 index 00000000..57230edf Binary files /dev/null and b/symm/t/modes/idea-cbc.regress differ diff --git a/symm/t/modes/idea-cfb.regress b/symm/t/modes/idea-cfb.regress new file mode 100644 index 00000000..76f0995b Binary files /dev/null and b/symm/t/modes/idea-cfb.regress differ diff --git a/symm/t/modes/idea-counter.regress b/symm/t/modes/idea-counter.regress new file mode 100644 index 00000000..d825c4d1 Binary files /dev/null and b/symm/t/modes/idea-counter.regress differ diff --git a/symm/t/modes/idea-ecb.regress b/symm/t/modes/idea-ecb.regress new file mode 100644 index 00000000..e573d529 Binary files /dev/null and b/symm/t/modes/idea-ecb.regress differ diff --git a/symm/t/modes/idea-ofb.regress b/symm/t/modes/idea-ofb.regress new file mode 100644 index 00000000..01fd5dc1 Binary files /dev/null and b/symm/t/modes/idea-ofb.regress differ diff --git a/symm/t/modes/mars-cbc.regress b/symm/t/modes/mars-cbc.regress new file mode 100644 index 00000000..30d4d7ec Binary files /dev/null and b/symm/t/modes/mars-cbc.regress differ diff --git a/symm/t/modes/mars-cfb.regress b/symm/t/modes/mars-cfb.regress new file mode 100644 index 00000000..0874aaa5 Binary files /dev/null and b/symm/t/modes/mars-cfb.regress differ diff --git a/symm/t/modes/mars-counter.regress b/symm/t/modes/mars-counter.regress new file mode 100644 index 00000000..145e9438 Binary files /dev/null and b/symm/t/modes/mars-counter.regress differ diff --git a/symm/t/modes/mars-ecb.regress b/symm/t/modes/mars-ecb.regress new file mode 100644 index 00000000..d7f96df2 Binary files /dev/null and b/symm/t/modes/mars-ecb.regress differ diff --git a/symm/t/modes/mars-ofb.regress b/symm/t/modes/mars-ofb.regress new file mode 100644 index 00000000..c29b704e Binary files /dev/null and b/symm/t/modes/mars-ofb.regress differ diff --git a/symm/t/modes/md2-mgf.regress b/symm/t/modes/md2-mgf.regress new file mode 100644 index 00000000..652a65e9 Binary files /dev/null and b/symm/t/modes/md2-mgf.regress differ diff --git a/symm/t/modes/md4-mgf.regress b/symm/t/modes/md4-mgf.regress new file mode 100644 index 00000000..e138a740 Binary files /dev/null and b/symm/t/modes/md4-mgf.regress differ diff --git a/symm/t/modes/md5-mgf.regress b/symm/t/modes/md5-mgf.regress new file mode 100644 index 00000000..96bd16a3 Binary files /dev/null and b/symm/t/modes/md5-mgf.regress differ diff --git a/symm/t/modes/noekeon-cbc.regress b/symm/t/modes/noekeon-cbc.regress new file mode 100644 index 00000000..5b3e218a Binary files /dev/null and b/symm/t/modes/noekeon-cbc.regress differ diff --git a/symm/t/modes/noekeon-cfb.regress b/symm/t/modes/noekeon-cfb.regress new file mode 100644 index 00000000..75ce9019 Binary files /dev/null and b/symm/t/modes/noekeon-cfb.regress differ diff --git a/symm/t/modes/noekeon-counter.regress b/symm/t/modes/noekeon-counter.regress new file mode 100644 index 00000000..464ff7f6 Binary files /dev/null and b/symm/t/modes/noekeon-counter.regress differ diff --git a/symm/t/modes/noekeon-ecb.regress b/symm/t/modes/noekeon-ecb.regress new file mode 100644 index 00000000..9a8efe49 Binary files /dev/null and b/symm/t/modes/noekeon-ecb.regress differ diff --git a/symm/t/modes/noekeon-ofb.regress b/symm/t/modes/noekeon-ofb.regress new file mode 100644 index 00000000..91cedd8b Binary files /dev/null and b/symm/t/modes/noekeon-ofb.regress differ diff --git a/symm/t/modes/rc2-cbc.regress b/symm/t/modes/rc2-cbc.regress new file mode 100644 index 00000000..8d49c5a5 Binary files /dev/null and b/symm/t/modes/rc2-cbc.regress differ diff --git a/symm/t/modes/rc2-cfb.regress b/symm/t/modes/rc2-cfb.regress new file mode 100644 index 00000000..71ca1727 Binary files /dev/null and b/symm/t/modes/rc2-cfb.regress differ diff --git a/symm/t/modes/rc2-counter.regress b/symm/t/modes/rc2-counter.regress new file mode 100644 index 00000000..f57e0318 Binary files /dev/null and b/symm/t/modes/rc2-counter.regress differ diff --git a/symm/t/modes/rc2-ecb.regress b/symm/t/modes/rc2-ecb.regress new file mode 100644 index 00000000..07910a78 Binary files /dev/null and b/symm/t/modes/rc2-ecb.regress differ diff --git a/symm/t/modes/rc2-ofb.regress b/symm/t/modes/rc2-ofb.regress new file mode 100644 index 00000000..39c837fe Binary files /dev/null and b/symm/t/modes/rc2-ofb.regress differ diff --git a/symm/t/modes/rc5-cbc.regress b/symm/t/modes/rc5-cbc.regress new file mode 100644 index 00000000..0689ba4d Binary files /dev/null and b/symm/t/modes/rc5-cbc.regress differ diff --git a/symm/t/modes/rc5-cfb.regress b/symm/t/modes/rc5-cfb.regress new file mode 100644 index 00000000..5cd4011b Binary files /dev/null and b/symm/t/modes/rc5-cfb.regress differ diff --git a/symm/t/modes/rc5-counter.regress b/symm/t/modes/rc5-counter.regress new file mode 100644 index 00000000..5700843b Binary files /dev/null and b/symm/t/modes/rc5-counter.regress differ diff --git a/symm/t/modes/rc5-ecb.regress b/symm/t/modes/rc5-ecb.regress new file mode 100644 index 00000000..0ed3ee6e Binary files /dev/null and b/symm/t/modes/rc5-ecb.regress differ diff --git a/symm/t/modes/rc5-ofb.regress b/symm/t/modes/rc5-ofb.regress new file mode 100644 index 00000000..28103d7c Binary files /dev/null and b/symm/t/modes/rc5-ofb.regress differ diff --git a/symm/t/modes/rijndael-cbc.regress b/symm/t/modes/rijndael-cbc.regress new file mode 100644 index 00000000..2d44c16f Binary files /dev/null and b/symm/t/modes/rijndael-cbc.regress differ diff --git a/symm/t/modes/rijndael-cfb.regress b/symm/t/modes/rijndael-cfb.regress new file mode 100644 index 00000000..d0cb1013 Binary files /dev/null and b/symm/t/modes/rijndael-cfb.regress differ diff --git a/symm/t/modes/rijndael-counter.regress b/symm/t/modes/rijndael-counter.regress new file mode 100644 index 00000000..49ae7af9 Binary files /dev/null and b/symm/t/modes/rijndael-counter.regress differ diff --git a/symm/t/modes/rijndael-ecb.regress b/symm/t/modes/rijndael-ecb.regress new file mode 100644 index 00000000..2668a62c Binary files /dev/null and b/symm/t/modes/rijndael-ecb.regress differ diff --git a/symm/t/modes/rijndael-ofb.regress b/symm/t/modes/rijndael-ofb.regress new file mode 100644 index 00000000..6bc7d199 Binary files /dev/null and b/symm/t/modes/rijndael-ofb.regress differ diff --git a/symm/t/modes/rijndael192-cbc.regress b/symm/t/modes/rijndael192-cbc.regress new file mode 100644 index 00000000..99673d9f Binary files /dev/null and b/symm/t/modes/rijndael192-cbc.regress differ diff --git a/symm/t/modes/rijndael192-cfb.regress b/symm/t/modes/rijndael192-cfb.regress new file mode 100644 index 00000000..899550e8 Binary files /dev/null and b/symm/t/modes/rijndael192-cfb.regress differ diff --git a/symm/t/modes/rijndael192-counter.regress b/symm/t/modes/rijndael192-counter.regress new file mode 100644 index 00000000..5b89d87a Binary files /dev/null and b/symm/t/modes/rijndael192-counter.regress differ diff --git a/symm/t/modes/rijndael192-ecb.regress b/symm/t/modes/rijndael192-ecb.regress new file mode 100644 index 00000000..3420f8ab Binary files /dev/null and b/symm/t/modes/rijndael192-ecb.regress differ diff --git a/symm/t/modes/rijndael192-ofb.regress b/symm/t/modes/rijndael192-ofb.regress new file mode 100644 index 00000000..6885dc2e Binary files /dev/null and b/symm/t/modes/rijndael192-ofb.regress differ diff --git a/symm/t/modes/rijndael256-cbc.regress b/symm/t/modes/rijndael256-cbc.regress new file mode 100644 index 00000000..d1f4f96f Binary files /dev/null and b/symm/t/modes/rijndael256-cbc.regress differ diff --git a/symm/t/modes/rijndael256-cfb.regress b/symm/t/modes/rijndael256-cfb.regress new file mode 100644 index 00000000..4e21cd6b Binary files /dev/null and b/symm/t/modes/rijndael256-cfb.regress differ diff --git a/symm/t/modes/rijndael256-counter.regress b/symm/t/modes/rijndael256-counter.regress new file mode 100644 index 00000000..a0eb2f3d Binary files /dev/null and b/symm/t/modes/rijndael256-counter.regress differ diff --git a/symm/t/modes/rijndael256-ecb.regress b/symm/t/modes/rijndael256-ecb.regress new file mode 100644 index 00000000..c82a4b29 Binary files /dev/null and b/symm/t/modes/rijndael256-ecb.regress differ diff --git a/symm/t/modes/rijndael256-ofb.regress b/symm/t/modes/rijndael256-ofb.regress new file mode 100644 index 00000000..45c40916 Binary files /dev/null and b/symm/t/modes/rijndael256-ofb.regress differ diff --git a/symm/t/modes/rmd128-mgf.regress b/symm/t/modes/rmd128-mgf.regress new file mode 100644 index 00000000..27b3f4cd Binary files /dev/null and b/symm/t/modes/rmd128-mgf.regress differ diff --git a/symm/t/modes/rmd160-mgf.regress b/symm/t/modes/rmd160-mgf.regress new file mode 100644 index 00000000..53d466f4 Binary files /dev/null and b/symm/t/modes/rmd160-mgf.regress differ diff --git a/symm/t/modes/rmd256-mgf.regress b/symm/t/modes/rmd256-mgf.regress new file mode 100644 index 00000000..4a15390b Binary files /dev/null and b/symm/t/modes/rmd256-mgf.regress differ diff --git a/symm/t/modes/rmd320-mgf.regress b/symm/t/modes/rmd320-mgf.regress new file mode 100644 index 00000000..82b10f3c Binary files /dev/null and b/symm/t/modes/rmd320-mgf.regress differ diff --git a/symm/t/modes/safer-cbc.regress b/symm/t/modes/safer-cbc.regress new file mode 100644 index 00000000..a23aa496 Binary files /dev/null and b/symm/t/modes/safer-cbc.regress differ diff --git a/symm/t/modes/safer-cfb.regress b/symm/t/modes/safer-cfb.regress new file mode 100644 index 00000000..0c49a5ca Binary files /dev/null and b/symm/t/modes/safer-cfb.regress differ diff --git a/symm/t/modes/safer-counter.regress b/symm/t/modes/safer-counter.regress new file mode 100644 index 00000000..03ff0972 Binary files /dev/null and b/symm/t/modes/safer-counter.regress differ diff --git a/symm/t/modes/safer-ecb.regress b/symm/t/modes/safer-ecb.regress new file mode 100644 index 00000000..882ff989 Binary files /dev/null and b/symm/t/modes/safer-ecb.regress differ diff --git a/symm/t/modes/safer-ofb.regress b/symm/t/modes/safer-ofb.regress new file mode 100644 index 00000000..b06625bb Binary files /dev/null and b/symm/t/modes/safer-ofb.regress differ diff --git a/symm/t/modes/safersk-cbc.regress b/symm/t/modes/safersk-cbc.regress new file mode 100644 index 00000000..9816c410 Binary files /dev/null and b/symm/t/modes/safersk-cbc.regress differ diff --git a/symm/t/modes/safersk-cfb.regress b/symm/t/modes/safersk-cfb.regress new file mode 100644 index 00000000..8db489f3 Binary files /dev/null and b/symm/t/modes/safersk-cfb.regress differ diff --git a/symm/t/modes/safersk-counter.regress b/symm/t/modes/safersk-counter.regress new file mode 100644 index 00000000..a40cd29c Binary files /dev/null and b/symm/t/modes/safersk-counter.regress differ diff --git a/symm/t/modes/safersk-ecb.regress b/symm/t/modes/safersk-ecb.regress new file mode 100644 index 00000000..fcba346d Binary files /dev/null and b/symm/t/modes/safersk-ecb.regress differ diff --git a/symm/t/modes/safersk-ofb.regress b/symm/t/modes/safersk-ofb.regress new file mode 100644 index 00000000..36288ccf Binary files /dev/null and b/symm/t/modes/safersk-ofb.regress differ diff --git a/symm/t/modes/serpent-cbc.regress b/symm/t/modes/serpent-cbc.regress new file mode 100644 index 00000000..0f879de0 Binary files /dev/null and b/symm/t/modes/serpent-cbc.regress differ diff --git a/symm/t/modes/serpent-cfb.regress b/symm/t/modes/serpent-cfb.regress new file mode 100644 index 00000000..0d275300 Binary files /dev/null and b/symm/t/modes/serpent-cfb.regress differ diff --git a/symm/t/modes/serpent-counter.regress b/symm/t/modes/serpent-counter.regress new file mode 100644 index 00000000..855d60a0 Binary files /dev/null and b/symm/t/modes/serpent-counter.regress differ diff --git a/symm/t/modes/serpent-ecb.regress b/symm/t/modes/serpent-ecb.regress new file mode 100644 index 00000000..5306e958 Binary files /dev/null and b/symm/t/modes/serpent-ecb.regress differ diff --git a/symm/t/modes/serpent-ofb.regress b/symm/t/modes/serpent-ofb.regress new file mode 100644 index 00000000..3b5e6e74 Binary files /dev/null and b/symm/t/modes/serpent-ofb.regress differ diff --git a/symm/t/modes/sha-mgf.regress b/symm/t/modes/sha-mgf.regress new file mode 100644 index 00000000..797011ac Binary files /dev/null and b/symm/t/modes/sha-mgf.regress differ diff --git a/symm/t/modes/sha224-mgf.regress b/symm/t/modes/sha224-mgf.regress new file mode 100644 index 00000000..559e8301 Binary files /dev/null and b/symm/t/modes/sha224-mgf.regress differ diff --git a/symm/t/modes/sha256-mgf.regress b/symm/t/modes/sha256-mgf.regress new file mode 100644 index 00000000..b6aa1417 Binary files /dev/null and b/symm/t/modes/sha256-mgf.regress differ diff --git a/symm/t/modes/sha3-224-mgf.regress b/symm/t/modes/sha3-224-mgf.regress new file mode 100644 index 00000000..5bd9f01f Binary files /dev/null and b/symm/t/modes/sha3-224-mgf.regress differ diff --git a/symm/t/modes/sha3-256-mgf.regress b/symm/t/modes/sha3-256-mgf.regress new file mode 100644 index 00000000..0324143f Binary files /dev/null and b/symm/t/modes/sha3-256-mgf.regress differ diff --git a/symm/t/modes/sha3-384-mgf.regress b/symm/t/modes/sha3-384-mgf.regress new file mode 100644 index 00000000..dc86c05e Binary files /dev/null and b/symm/t/modes/sha3-384-mgf.regress differ diff --git a/symm/t/modes/sha3-512-mgf.regress b/symm/t/modes/sha3-512-mgf.regress new file mode 100644 index 00000000..e9b0fe0c Binary files /dev/null and b/symm/t/modes/sha3-512-mgf.regress differ diff --git a/symm/t/modes/sha384-mgf.regress b/symm/t/modes/sha384-mgf.regress new file mode 100644 index 00000000..bf688b2c Binary files /dev/null and b/symm/t/modes/sha384-mgf.regress differ diff --git a/symm/t/modes/sha512-224-mgf.regress b/symm/t/modes/sha512-224-mgf.regress new file mode 100644 index 00000000..ccd94bab Binary files /dev/null and b/symm/t/modes/sha512-224-mgf.regress differ diff --git a/symm/t/modes/sha512-256-mgf.regress b/symm/t/modes/sha512-256-mgf.regress new file mode 100644 index 00000000..a01aa7ae Binary files /dev/null and b/symm/t/modes/sha512-256-mgf.regress differ diff --git a/symm/t/modes/sha512-mgf.regress b/symm/t/modes/sha512-mgf.regress new file mode 100644 index 00000000..3dae6fa8 Binary files /dev/null and b/symm/t/modes/sha512-mgf.regress differ diff --git a/symm/t/modes/skipjack-cbc.regress b/symm/t/modes/skipjack-cbc.regress new file mode 100644 index 00000000..a1fad973 Binary files /dev/null and b/symm/t/modes/skipjack-cbc.regress differ diff --git a/symm/t/modes/skipjack-cfb.regress b/symm/t/modes/skipjack-cfb.regress new file mode 100644 index 00000000..31869861 Binary files /dev/null and b/symm/t/modes/skipjack-cfb.regress differ diff --git a/symm/t/modes/skipjack-counter.regress b/symm/t/modes/skipjack-counter.regress new file mode 100644 index 00000000..33a0ab11 Binary files /dev/null and b/symm/t/modes/skipjack-counter.regress differ diff --git a/symm/t/modes/skipjack-ecb.regress b/symm/t/modes/skipjack-ecb.regress new file mode 100644 index 00000000..6cbf31c6 Binary files /dev/null and b/symm/t/modes/skipjack-ecb.regress differ diff --git a/symm/t/modes/skipjack-ofb.regress b/symm/t/modes/skipjack-ofb.regress new file mode 100644 index 00000000..2ff46ea5 Binary files /dev/null and b/symm/t/modes/skipjack-ofb.regress differ diff --git a/symm/t/modes/square-cbc.regress b/symm/t/modes/square-cbc.regress new file mode 100644 index 00000000..40008aa6 Binary files /dev/null and b/symm/t/modes/square-cbc.regress differ diff --git a/symm/t/modes/square-cfb.regress b/symm/t/modes/square-cfb.regress new file mode 100644 index 00000000..b8dda4e2 Binary files /dev/null and b/symm/t/modes/square-cfb.regress differ diff --git a/symm/t/modes/square-counter.regress b/symm/t/modes/square-counter.regress new file mode 100644 index 00000000..39be028a Binary files /dev/null and b/symm/t/modes/square-counter.regress differ diff --git a/symm/t/modes/square-ecb.regress b/symm/t/modes/square-ecb.regress new file mode 100644 index 00000000..8aeff530 Binary files /dev/null and b/symm/t/modes/square-ecb.regress differ diff --git a/symm/t/modes/square-ofb.regress b/symm/t/modes/square-ofb.regress new file mode 100644 index 00000000..f718ed33 Binary files /dev/null and b/symm/t/modes/square-ofb.regress differ diff --git a/symm/t/modes/tea-cbc.regress b/symm/t/modes/tea-cbc.regress new file mode 100644 index 00000000..103aa1d5 Binary files /dev/null and b/symm/t/modes/tea-cbc.regress differ diff --git a/symm/t/modes/tea-cfb.regress b/symm/t/modes/tea-cfb.regress new file mode 100644 index 00000000..78d0c7b9 Binary files /dev/null and b/symm/t/modes/tea-cfb.regress differ diff --git a/symm/t/modes/tea-counter.regress b/symm/t/modes/tea-counter.regress new file mode 100644 index 00000000..d637d2dd Binary files /dev/null and b/symm/t/modes/tea-counter.regress differ diff --git a/symm/t/modes/tea-ecb.regress b/symm/t/modes/tea-ecb.regress new file mode 100644 index 00000000..8524c0cc Binary files /dev/null and b/symm/t/modes/tea-ecb.regress differ diff --git a/symm/t/modes/tea-ofb.regress b/symm/t/modes/tea-ofb.regress new file mode 100644 index 00000000..679611be Binary files /dev/null and b/symm/t/modes/tea-ofb.regress differ diff --git a/symm/t/modes/tiger-mgf.regress b/symm/t/modes/tiger-mgf.regress new file mode 100644 index 00000000..497a490a Binary files /dev/null and b/symm/t/modes/tiger-mgf.regress differ diff --git a/symm/t/modes/twofish-cbc.regress b/symm/t/modes/twofish-cbc.regress new file mode 100644 index 00000000..bf019292 Binary files /dev/null and b/symm/t/modes/twofish-cbc.regress differ diff --git a/symm/t/modes/twofish-cfb.regress b/symm/t/modes/twofish-cfb.regress new file mode 100644 index 00000000..c3f9ea28 Binary files /dev/null and b/symm/t/modes/twofish-cfb.regress differ diff --git a/symm/t/modes/twofish-counter.regress b/symm/t/modes/twofish-counter.regress new file mode 100644 index 00000000..ad27602c Binary files /dev/null and b/symm/t/modes/twofish-counter.regress differ diff --git a/symm/t/modes/twofish-ecb.regress b/symm/t/modes/twofish-ecb.regress new file mode 100644 index 00000000..58e4f935 Binary files /dev/null and b/symm/t/modes/twofish-ecb.regress differ diff --git a/symm/t/modes/twofish-ofb.regress b/symm/t/modes/twofish-ofb.regress new file mode 100644 index 00000000..a11550a2 Binary files /dev/null and b/symm/t/modes/twofish-ofb.regress differ diff --git a/symm/t/modes/whirlpool-mgf.regress b/symm/t/modes/whirlpool-mgf.regress new file mode 100644 index 00000000..0f48f399 Binary files /dev/null and b/symm/t/modes/whirlpool-mgf.regress differ diff --git a/symm/t/modes/whirlpool256-mgf.regress b/symm/t/modes/whirlpool256-mgf.regress new file mode 100644 index 00000000..50519543 Binary files /dev/null and b/symm/t/modes/whirlpool256-mgf.regress differ diff --git a/symm/t/modes/xtea-cbc.regress b/symm/t/modes/xtea-cbc.regress new file mode 100644 index 00000000..04f4ea28 Binary files /dev/null and b/symm/t/modes/xtea-cbc.regress differ diff --git a/symm/t/modes/xtea-cfb.regress b/symm/t/modes/xtea-cfb.regress new file mode 100644 index 00000000..3bde823c Binary files /dev/null and b/symm/t/modes/xtea-cfb.regress differ diff --git a/symm/t/modes/xtea-counter.regress b/symm/t/modes/xtea-counter.regress new file mode 100644 index 00000000..f56c42a2 Binary files /dev/null and b/symm/t/modes/xtea-counter.regress differ diff --git a/symm/t/modes/xtea-ecb.regress b/symm/t/modes/xtea-ecb.regress new file mode 100644 index 00000000..cc252a6c Binary files /dev/null and b/symm/t/modes/xtea-ecb.regress differ diff --git a/symm/t/modes/xtea-ofb.regress b/symm/t/modes/xtea-ofb.regress new file mode 100644 index 00000000..ef53aff3 Binary files /dev/null and b/symm/t/modes/xtea-ofb.regress differ diff --git a/symm/t/noekeon b/symm/t/noekeon index 07647327..02382288 100644 --- a/symm/t/noekeon +++ b/symm/t/noekeon @@ -8,3 +8,246 @@ noekeon { ba6933819299c71699a99f08f678178b 52f88a7b283c1f7bdf7b6faa5011c7d8 5096f2bfc82ae6e2d9495515c277fa70; } + +noekeon-cmac { + e4bef260d7bcda163547d348b7551195 + "" + 2863ef2fdd68856576cdd771bfa6f2d5; + e77022907dd1dff7dac5c9941d26d0c6 + eb + f8e7683bb1eaa6647a054678315b5eda; + 14ad568f86edd1dc9268eeee533285a6 + ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a8 + 0a792a2d00ebcf99531795f4b5014e2e; + 77ff77bf79192a5b50ade5d9cd739a3d + 1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10 + c123e79e5caf935e4534444d32d814d3; +} + +noekeon-ccm { + e4bef260d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9 + "" + "" + "" + 49ba308e; + 941d26d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b68 + 9d + "" + "" + bf7a3a76; + aaa9060d2d4b6003062365b0a54364c7 + 6c160f11896c4794846ecf + "" + a1 + 07 + f4749361; + 4a7130c9f137120634c9519848a877ff + 77bf79192a5b50ade5 + d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10 + 997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7 + 4c78845e20c686f9ff85982d36d3e9aa511ca2e24d03978efbcc2728d499114cfec92bac5f9913c6fab485e7dced9599 + ed048b86e5dbb933f5893750dc0634cd; + b1cc49ae1d50c38201a894476b3f102b + 752eb9529533966f27 + 043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac + 0c825df862df85bf1bb99434c39ce83a392f0e03ca915677bfc6f7de8cf1643c70f679f8dc8d245fb2c84be5f05b5e6064ff017589 + c9d921b8c460e2dab218d13a0609a344; +} + +noekeon-eax { + e4bef260d7bcda163547d348b7551195 + "" + "" + "" + "" + 086d221cf45f48c8c1f0c176c227db42; + e77022907dd1dff7dac5c9941d26d0c6 + eb + "" + "" + "" + 5599da97576ed0f456791a6d00e17288; + 14ad568f86edd1dc9268eeee533285a6 + "" + ed + "" + "" + 40e6658bc9910a80906ad1337c633782; + 810c9b689daaa9060d2d4b6003062365 + "" + "" + b0 + f2 + 205c5f8a0dbeefddbead7141069de5d7; + a54364c76c160f11896c4794846ecfa1 + 4a7130c9f137120634c9519848a877ff + 77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + 3aae83e95da014773b3575f62054485064a2e2070a0449ab21a5dcdda2ff10d572e475a29d0bb4710a95c109641de055 + 8dc62b8af3aeb306e9469d238906612e; + 05e505da1435dceaa7b1cc49ae1d50c3 + 8201a894476b3f102b752eb9529533 + 966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4 + f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe + 5fe35fcbf55279bdca2295b483181ccff932771ccd59aa3e35b39b6564032af118547a9704fffe57c789a88b70c7eca6eaabea82b8 + 4953808f5678ba307676326facca87d2; +} + +noekeon-gcm { + e4bef260d7bcda163547d348b7551195 + "" + "" + "" + "" + d739a8af18e930e49547f57c7454eb47; + e77022907dd1dff7dac5c9941d26d0c6 + eb + "" + "" + "" + 6b26f591dfb442623c1590caefa4d323; + 14ad568f86edd1dc9268eeee533285a6 + "" + ed + "" + "" + 77fc8f1632e4f4294f6b9df680afc350; + 810c9b689daaa9060d2d4b6003062365 + "" + "" + b0 + 26 + e6aa7e364110e5c886e865b8fbffbece; + a54364c76c160f11896c4794846ecfa1 + 4a7130c9f137120634c9519848a877ff + 77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + 7d5aef8b63a47da6a441fa4e9b36c31c39c58ac1d95728acf41ca1f81784cfb58b66ad385bc75e43062531cb3e5a5662 + 8dcf9c1d3abaf968a359afb853e866bc; + 05e505da1435dceaa7b1cc49ae1d50c3 + 8201a894476b3f102b752eb9 + 529533966f27043eb621b7f65b000961040ef2 + f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378 + 55ada77e6525df0ec6c424d43cedc25f04a9b1d37d2813c1ebc6a35d157c3137cb5f04753e86676a111d72e7303bb8430ac48f65fa5b125e7a + 8c0d31d253b49759c1289ca15bdd068a; + c5b93bf4f2aad2605faee2b03fb648e2 + 7fff63102758fe2b69ac26afa33498 + 29b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563 + 259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f76 + 3e98ad97b1901fa089ddb06696ad688a3de2274b81d49c3198c17b2c1bd19556d0679d64d61f034880c89f111631bf78c4512599d7 + 5942a749a90e4af467a8a5782590dc69; +} + +noekeon-ocb1 { + e4bef260d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9941d26d0c6 + "" + "" + "" + 5081208cd2d5472d061211afba47e43a; + eb14ad568f86edd1dc9268eeee533285 + a6ed810c9b689daaa9060d2d4b600306 + 23 + "" + "" + e7162034dc92f809d9d9e7e41d9018bc; + 65b0a54364c76c160f11896c4794846e + cfa14a7130c9f137120634c9519848a8 + "" + 77 + 59 + fb7d568a9d2b0d8d33ca41930bd73d3f; + ff77bf79192a5b50ade5d9cd739a3d1f + 337f29549e6b0d27a4ba234085406a61 + "" + 36512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f50804 + 86ec994914704bd64a4a2b519d43c2efd4554cd0e7cc41a91f25137ac94218e5622df9670340515ef947f90cfe6c0484 + e72bacd856c8262a0d0bfc10ffb9fdd4; + 6733d9ff61cdbda3b3e9878731ebfedd + 4705e505da1435dceaa7b1cc49ae1d50 + c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda1 + 9d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2 + 83eac3304197940d9942306411887d6809d9f04a4bdcea111a877f2579779bbb9dcc0738ea8e05cfd3aa48823ca8abd8 + 76d9c5343a98b1a9e90c8ce4978efd2b; + 605faee2b03fb648e27fff63102758fe + 2b69ac26afa3349829b94586306fed54 + "" + 154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800 + 18adeeddc2d0656141002e939240aa51080969442d958a78b499fb587f585c6688fed54c528603e75c756c490fa9f1486775a01514 + 1974d395a27da8b706de45c0821c6e68; + df9fcbaca48b77dba189196d1ebba10b + 0467cb9fc2712a199e533fa9156308cd + ec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0b + ad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b + 8c38ca85e4711e354e2662ff977da8ed51aca92d50c1fc40e21fde2e481f93e5c9fc454881eea55c8b6758ce6bf6adff18e01825af + cbe1c75a2354cf5dc1df8a6eb6ede687; +} + +noekeon-pmac1 { + e4bef260d7bcda163547d348b7551195 + "" + 12679e29381d4258973a3d59f3405ec9; + e77022907dd1dff7dac5c9941d26d0c6 + eb + a8cf4e78783c841939afff131c3b0b42; + 14ad568f86edd1dc9268eeee533285a6 + ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a8 + 1b01bbe2a8cbae52485e4d410f94ce1e; + 77ff77bf79192a5b50ade5d9cd739a3d + 1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10 + 35b9675a79680b83422e4282cc260583; +} + +noekeon-ocb3 { + e4bef260d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9941d26 + "" + "" + "" + 064d07192f9b79d8bc4611a94783465b; + d0c6eb14ad568f86edd1dc9268eeee53 + 3285a6ed810c9b689daaa9060d2d + 4b + "" + "" + 37ad7dbe61111839a2bbead7eec6358a; + 6003062365b0a54364c76c160f11896c + 4794846ecfa14a7130c9f1371206 + "" + 34 + 76 + 73f39959389362724e3785d929b00e8c; + c9519848a877ff77bf79192a5b50ade5 + d9cd739a3d1f337f29549e + "" + 6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029 + 820db0cbad206848e689523feda637ed12f58eaa9f133457937c505778b55369994f1c339ca3d2c044578450d5905c22 + a0205c94e65a8712262a1d127f9d22da; + df3e6057acc87638f508046733d9ff61 + cdbda3b3e9878731ebfedd4705 + e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2 + fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3 + d79866f055cda0abb2ad06098f8c651ed32d5550d021bfd59fffd34433b04483d0d402fce3309a760720fadd094c8ee1 + 14c60ff87068d3d52be11c8472174f77; + ad54efc9a38378c5b93bf4f2aad2605f + aee2b03fb648e27fff63102758fe + "" + 2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f + dcda3a90b5db824f1d54c569db8d543bb323ff0aa596a8779b7b94c3f397b193e3762cea731fe84ed5e7bd517641466550043faad9 + b92101660872e1e7a951e8d8bab834c9; + 9eb53b571ea629c54d57dd2d42f70800 + df9fcbaca48b77dba189196d1ebb + a10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b + 0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da67 + 42b20072cef90e896f11993737b645f8e42c172527cd4ddaa5ec2e54d4bb7f234062d707b63c87624b8e16273bce20e835f3374199 + 915583e7c80edec73b6d59c12a2a196f; +} + +noekeon-ocb3-mct { + 16 4d9b245d6fab392f1c5364a2ef5b96fb; + 16 3b08aa07a8a40dc29e87a831; + 16 9e400fc6449969f2; +} diff --git a/symm/t/rc2 b/symm/t/rc2 index ed90d3f4..78c134a6 100644 --- a/symm/t/rc2 +++ b/symm/t/rc2 @@ -11,3 +11,912 @@ rc2 { 88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e 129 0000000000000000 5b78d3a43dfff1f1; } + +rc2-cmac { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268ee + "" + 994f0987c07cbba3; + ee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a71 + 30 + 93e320d01033928d; + c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + 406a6136512061f7080cc07df0591d8fa21f2dd88374d8cd + ba4c9972985a3777; + e8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731eb + fedd4705e505da1435dceaa7b1cc49ae1d50c3 + fb945bb5060a692c; + 8201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa33498 + "" + 33d92d711438bf90; + 29b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a + 22 + d387a2b3add24161; + 260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22b + b02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2a + 200579382f8fefd7; + ebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98 + ef1f0446b42fb144d44b6d00f06dc188d472a7 + 72b14ddabaa01c99; + 84e0c6f21195a3b9f4ae985511265febd11c16 + "" + 35d8b20b8aedd4c5; + 4720eef9eb1c8dd0b00951f284649016ed0045 + 63 + 3c8051aab08b5e2a; + 31854bc78bf43966eb0cfa9138ddc399084456 + 08fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126 + d71ceb7b023f4a2a; + b807e6daa089c3f9099c5ffb824173d7634c04 + 226f30cbb7f0e4a973a8cd190107314717a774 + 7cb1fd4850d2b1cb; + 56f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9b + "" + 8db7f9520ec921d2; + c597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9c + e0 + 53c35ba18d421787; + 21a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18c + bfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458 + d6409d3b48a62658; + cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957 + f4b03cf43e89957f9a3e8128f8743d16687b7b + 9ffecd00a5ce33b6; +} + +rc2-ccm { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268ee + ee5332 + "" + "" + "" + 0e756e3d; + 85a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1 + 371206 + 34 + "" + "" + 88075561; + c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a61365120 + 61f708 + "" + 0c + e4 + 677a1fdd; + c07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f50804 + 6733d9ff61 + cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49 + ae1d50c38201a894476b3f102b752eb9529533966f27043e + aa2e353749ab572e5ea55be5be368bae0ca3cd5604ec9c06 + bbdce19a0df3c05b; + b621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbb + b18ac6c95a + 97a48030370c33d090c54215abd6b3ad54efc9 + a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac + a1b2416f66d57ca9034827ff55b17cfac62108e8a10a62c3aec1de6d6a + af60612dfed6edb3; + 26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c + 6b08ac + "" + "" + "" + ef7e40ab; + 8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e79 + 52d22b + b0 + "" + "" + 9cef3d08; + 2d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd + 52147e + "" + d1 + a9 + 0e3165e9; + 2ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d1 + 26b807e6da + a089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973 + a8cd190107314717a77456f3ff669c732b58db8f48af65f7 + 79a7ec7b8d3aad1c29ce22222d9089766c6892e25284af53 + 1a749a4b280e03eb; + cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957 + f4b03cf43e + 89957f9a3e8128f8743d16687b7bb8deb9bd20 + 5b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac845139958701 + c1255583506986b100df1504190df39ec531be3506347bc3db4ab4ec82 + 993490ca3359ed04; + 1677508a15dde524af3e2bee0646541a42c2ec + ccb44d + "" + "" + "" + 2848a767; + 65bad397abfaf529ee41cf9a05c7efedef3401 + 539c51 + d2 + "" + "" + e0651099; + a90bbf7f1bfc338ab0ef5746ea8fdcccd213e3 + 3f7e8a + "" + 57 + a9 + 9135e83e; + 18fd25014107c8e7d715a92add9589d1f5c054 + b2d9835146 + 05ec590294a319b9802068a9f891bc5ba5afabf8c3122d12 + d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe07 + a0219d75977a704b34340dae9a6f96be4baaa1ad3ee96afa + b1e6a4f9015ad908; + 9753ee1a957eb6d6699e6b7ea2725cb2dac07e + cde95759ac + 46fee6dda7abc8ad68daac90cfe22d2f1f2968 + cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d40 + 612f7d0ab987bbd987e78707fa59388a40cd95b609e3b0df2298712134 + 242d9a4c7c587d14; + 5e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b954 + 60938d + "" + "" + "" + 9ebdeb8f; + e1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186dd + f1f6a7 + a3 + "" + "" + c53713f3; + aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba600 + 768175 + "" + 23 + ca + 704b73f9; + bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a833 + 1f0a170b66 + 283e4f834a06148f302c3973accd56f6f24e33958b8c2e23 + 52fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48a + 49e3c85b0d02dd9f89914d75405cfac2f343deccb9d98391 + 95c00f9b22962366; + fa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315 + 799dc875fb + a578c8ec4837898a92142b5b0677da1ac27311 + 7b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d + 8eccebfa67d50519fadda30deee9c4d16575a61eb68adf6157271bdabd + 1dbaccd5b26fc6e2; +} + +rc2-eax { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268ee + "" + "" + "" + "" + 493b1fd04ede5d08; + ee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a71 + 30 + "" + "" + "" + 21a99e853cf8d624; + c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + "" + 40 + "" + "" + c2a4952faeb51fe5; + 6a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e + "" + "" + 60 + d2 + bf5432b8192d764c; + 57acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c3 + 8201a894476b3f10 + 2b752eb9529533966f27043eb621b7f65b000961040ef2f9 + b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57b + f9c3cc1576f674b14e65fbe890be777d513381d3fbfaf3b6 + 3b7bbf2f56718d0b; + b3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605f + aee2b03fb648e2 + 7fff63102758fe2b69ac26afa3349829b94586 + 306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474 + 8d354144a9ae2bfb22f92a7c7bc3655d62b2b56d972a0b48fdc527118a + 168314d144ee4c2f; + fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe836813111 + "" + "" + "" + "" + 8e3a0ea494b5dd15; + 5c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af + 58 + "" + "" + "" + 3bb40705efd17087; + 13b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d4 + "" + 4b + "" + "" + 02dc7bc996b3d08a; + 6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973 + "" + "" + a8 + 46 + 593604619e5f140b; + cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd + 409b687fa3a6827b + 480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a + 3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cda + b775f9f9970f69be179df624ffa0a971fd60e1a77897730b + 1f3bee3056b77bef; + d9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319 + b9802068a9f891 + bc5ba5afabf8c3122d12d7ff3c41122d70d17d + 4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea272 + e4ad70206a32030a723a97c5fa7c051f0e47e4c419567c9f2465e6082b + b4e14cf29446000e; + 5cb2dac07ecde95759ac46fee6dda7abc8ad68 + "" + "" + "" + "" + e48136f1558ef9d4; + daac90cfe22d2f1f2968cc42fa8b669ed3bb35 + 42 + "" + "" + "" + 75a875a6cf6822dc; + a9cf44bbc8c6254d980398bd94e66eb4563d40 + "" + 5e + "" + "" + aff6510c3cfc9cf8; + 51881e99027b8ab9aea3ccf860b0009740763d + "" + "" + 96 + 73 + 0fbcddfb90453138; + 836c5f87b95460938de1288c69d80ea12ff4bb + 5f069b8a2e86041c + 1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b3 + 5b15ffaa6c36800d9645563a308ba60076817523bd2abf12 + 8c0f4a82cdc742cf10c6bcd81f08fe54d44602b6b04d84cb + 6048b808054d2c5f; + 61b089d8f23a9c2835076a23faac2cdd67771c + c667a8331f0a17 + 0b66283e4f834a06148f302c3973accd56f6f2 + 4e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8 + b136f77a805e9042723b12db98a1ab0c8af27b687ea3b81bd09cf15d20 + 94b18788b3964b32; + f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c48 + "" + "" + "" + "" + 441faa27cc4c5c56; + 6315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b + 45 + "" + "" + "" + eae3c4243cea46f9; + bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d + "" + 38 + "" + "" + 9a3430a79df38876; + 0d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf + "" + "" + 66 + 2c + 0cb5f535e70f4099; + fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe4 + 26a5a0e80f678d40 + 4147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959 + b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f + 6a855a701998a62f385b9ec42102a67ef354925d18569dd8 + eac5dfe4f5cbfff8; + 5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf8 + 556b7aa7769459 + 48d1b8834df2196c92ec1718dcdeee0d52d953 + 9726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfb + 9cf8b628ab6c3e8c69c289c3564027ff0de5e6bcecc38c05b8d1b7ec0a + fd274b8e3c469eb6; +} + +rc2-gcm { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268ee + "" + "" + "" + "" + 359ae96bacf96c86; + ee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a71 + 30 + "" + "" + "" + b106f982ce0fa16f; + c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + "" + 40 + "" + "" + 83c2efaff3e6fdf8; + 6a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e + "" + "" + 60 + c9 + dcac5bc0a6fc80b2; + 57acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c3 + 8201a894476b3f10 + 2b752eb9529533966f27043eb621b7f65b000961040ef2f9 + b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57b + 9c8dd0c92811769d381b46a75e60b5d80aebe054d178080f + bae3d5a852937cf2; + b3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605f + aee2b03f + b648e27fff63102758fe2b + 69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72 + 24efd192d24c0a27bb0453a186632e8084dee9028fd647362aa26cf46ed118f682 + 1505f15227faa14f; + 807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b + 77dba189196d1e + bba10b0467cb9fc2712a199e533fa9156308cd + ec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c + fe9f005b0bbe7851e82e3e55aadc6fa3297c4dc6aac7da88eea83d77c1 + ca6d92a0f8474851; + 571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d + "" + "" + "" + "" + 644405a0cd8f478c; + 7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52 + 14 + "" + "" + "" + 986911f8fb61ffd2; + 7ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc84 + "" + 24 + "" + "" + 55348e0c9fadf225; + d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc17 + "" + "" + 70 + 63 + 399484cb038779bb; + a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee06 + 46541a42c2ecccb4 + 4d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2 + a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718 + c734efcfe1131a326af5fd518ab1033e7ffd7c4eb825b4c1 + 8255ef3dc1ff72a3; + fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b66 + 9ed3bb35 + 42a9cf44bbc8c6254d9803 + 98bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f + 7b2425dc58e780f0ab6b356cdb6ad2223d2dd69372109f08203100aa9095ec1551 + 094f16bdf157a900; + 87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33 + 958b8c2e2352fd + 61e4fa8fec816ac861a8b33779f09e7a10fc02 + a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c4863 + 1118c134e5ab39c5332fba8f3e0a566361c72bc4fd4a14219400ac57e7 + b8a684bad429d427; + 15799dc875fba578c8ec4837898a92142b5b06 + "" + "" + "" + "" + 441a5fc1a7aa3965; + 77da1ac273117b45bcfff5d5f8b6fde2893232 + a9 + "" + "" + "" + c2d97eafb2d4dec5; + f81d14517ffae475f6b94a43a67b3d380d2f9a + "" + aa + "" + "" + 137e2f9a5fbfaed9; + fe2dd721c0095c8808847689211450ba8095ff + "" + "" + ab + 8e + 1499fe34d82b9009; + 1eaadf66fd22ac1976063e113ab61f813e28a1 + 397a7974a1d7f422 + 0c785fe426a5a0e80f678d404147842941feeffdc2eb44dc + 8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e515 + 46c4eff1fd15b9be037e2e240b8845cc9e7e2530ae6214ea + 9feaa7393f439893; + 0686d2301b43a15a84e81d7f5cedaa49e2414e + bf47970e + 560475cff206877de69146 + acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726 + 7af0b728198469b00a3792e3640858ea8e10f4f9a0ee2f97b007f3961499d92d0d + 1d5b27a15b866945; + d2810391b3f9d10c39b07ae8f08ce7cee4758a + 386a9943e97ded + fbe61e737882cd09c2b9a80f34c0fde11c2481 + b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe084 + dab65bbaad4fa9e2aeee14886c89799acfd26a90de80cd6851f05113d3 + c547859e516e9528; + 85290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb + "" + "" + "" + "" + 666def937cca91b5; + 6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91c + b9 + "" + "" + "" + cb3f188911d99a1a; + d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0 + "" + d7 + "" + "" + 223747afb3570769; + cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3d + "" + "" + f6 + f4 + 6ae1ee13e1831acb; + c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d73d1 + 92ee53b3f3ebd66d + dd98cedbe88e245de25b1593b70f8601562d90a9b59ed034 + a867642d25d54756fa5c47f16f64b837bb4926214211a1c6 + d995a4197fa15265ee44b445bc0d3940c486f9c34ba9077e + 0b047045426e23e6; + 96ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0 + d5ae7be8 + dbf98e4ffed2cf6b1372a5 + aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b9 + a4ed2fa0d3f42b2c3270ac0801aeaa7f28f57b101c8a9a1c0e45a046e9c6887b00 + 4c3c11a4709bcf9c; + 6856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597 + a1406d465b7b14 + 19ea51cf858f938f6daafbd656445a09898eaa + 96ffc3d1d2e31e4e34c94b8bfae64825ecd75a66d88eedb969ffe07669 + a1a0fe6856d107a0b49d164b72c0102a06bfc6ea17723f7587fab4808c + d797a4abd2ac973e; +} + +rc2-ocb1 { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268ee + ee533285a6ed810c + "" + "" + "" + 1a9b5d9930de70b3; + 9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9 + 519848a877ff77bf + 79 + "" + "" + c8a18423542f2476; + 192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8f + a21f2dd88374d8cd + "" + e8 + 65 + 1ad7745b69b0db1f; + e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfe + dd4705e505da1435 + "" + dceaa7b1cc49ae1d50c38201a894476b3f102b752eb95295 + 702a8f6236f63b37d12754e285b48acd278a5dd319781c47 + 4aed0840ec1cbc36; + 33966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb5 + 7bb3a4f3ebbbb18a + c6c95a97a48030370c33d090c54215abd6b3ad54efc9a383 + 78c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe + 63872e8fa08cbc02a9b67199cf4f8e805df8021d7dc7b857 + 7dc44cfa7b6a75c1; + 2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474 + fd71d891f24bb65d + "" + 1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba1 + 0e8b2f665c8e05920b18889a94a59262da8d5511e504ff00740151570d + aa8fbbd1631944b9; + 89196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f530 + 6ceb0c6b08ac8b0a + 22260c571b4a42bb8fdb233bfa6a5cfb0bad7d + 95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5 + fa9b97df764582e8b06700b70f488912e52bb40512b7e82546c98beea3 + 6125dbe65becfe77; + b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d07983 + 91805da08da3aefc + "" + "" + "" + 201550d036fd21c4; + 5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae9855 + 11265febd11c1647 + 20 + "" + "" + 980aada67611e269; + eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e17 + 21b730374ffc9bc5 + "" + 97 + a0 + 772be2781de4d5f1; + f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d + 16687b7bb8deb9bd + "" + 205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac + 935c1246b3c54e88b1612b1ae91add5d006c1da2eee504bf + cb750259096356be; + 8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3 + 122d12d7ff3c4112 + 2d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a95 + 7eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7 + e934e27dfd22901f7dee3fbdbd8380d67e381b1b0a969ef5 + 00818ef2133898d7; + abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa + 6c36800d9645563a + "" + 308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67 + 2d45ecd08b4263bcdcde76394694aadf336f30ba6b70a6109cc0c01041 + e1d92d792d66bbd0; + 771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fd + e2893232a9f81d14 + 517ffae475f6b94a43a67b3d380d2f9aaafe2d + d721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e + 801610881c1b88c3db1db411c93abbac039ff78a579e99226ebecc9b95 + 21d1073d1325dd61; + 113ab61f813e28a1397a7974a1d7f4220c785f + e426a5a0e80f678d + "" + "" + "" + 4366d16a510e7a2d; + 404147842941feeffdc2eb44dc8c0d5e8f444f + 7f4e0c893959b74d + c2 + "" + "" + 71128105ccb95e0c; + 3a7bb40e7e0013e5150686d2301b43a15a84e8 + 1d7f5cedaa49e241 + "" + 4e + 7b + 2f6c2965368d5936; + bf47970e560475cff206877de69146acc3ab6c + f8556b7aa7769459 + "" + 48d1b8834df2196c92ec1718dcdeee0d52d9539726d28103 + 3ab97a491b334616b5320f00b70e5e3620d36e5286b74ca3 + d3584dde26228442; + 91b3f9d10c39b07ae8f08ce7cee4758a386a99 + 43e97dedfbe61e73 + 7882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a + 9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d + d9fe5001eec9f51d5650f640a1acd392b3eb4cb1edde5d31 + b9c26d9e3edb786f; + 87d13b07398a1458c2c6b61dbdbc1cccada8c1 + a0a9aabb6c4e3c35 + "" + 54f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921056b7d + 3a35872aae6ecc5f2db7d75ba96b45d22646c61c41ecaa1be26c4685d0 + 9f54725515309904; + e74fc9a9b37154ce6c0b396179d31f06a1dd59 + 82cbc0d7cb23841d + a1ae8f4ae480cda98ad6cf2bacf6f9fd3f8213 + 30c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c9678 + 595e1b17cf4e6f603f4f37c5cc9f95960010ab062be907ea011276f6cc + 6cd3322bc4f3e0ec; + 8d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601 + 562d90a9b59ed034 + "" + "" + "" + 39204a02c689b225; + a867642d25d54756fa5c47f16f64b837bb4926214211a1c696ba17 + 2010abb433922a22 + d9 + "" + "" + 050a3b74030d78b6; + fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b + 1372a5aa47b54fd9 + "" + d7 + f7 + c80142d220c7ce79; + 0c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b9 + 6856beca34fd6544 + "" + bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b + a317166b0030c8c02542e56149c7169f92667fa0f1825571 + e1f6c6acb9532013; + 7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e3 + 1e4e34c94b8bfae6 + 4825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d0 + 99f47166edf54538e88fbf433a7ff212085179e79771f6ee + bf9a3249cfaef471b99720132fe379a074cc10927ed689fc + f60b7355eb51cac1; + e7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e + 771702fb1901ecfc + "" + 8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c738f4 + 287fa9c3540fc7adbfaf8a35cb932dbf3ec8be9b1c40ab18d34b1f82bf + a1789324aa8ffae5; + cb0f58a1e34c8b15ad930c1b627235a2cb84241986c251f5b70be2 + 367f047265264e0d + a72efe8995e6c932a17eab511eddb8e4ba463c + 663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd40088d5be74088e4 + f2433dd6f072fe804e258d6facf08e8798a615510c1cd0f1283f7b172b + b4cee725242787cd; +} + +rc2-pmac1 { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268ee + "" + 0e2341b111c8fa18; + ee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a71 + 30 + 73e15def05b8727d; + c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + 406a6136512061f7080cc07df0591d8fa21f2dd88374d8cd + 9a5cf16bab880541; + e8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731eb + fedd4705e505da1435dceaa7b1cc49ae1d50c3 + 0573bcdf6c429f04; + 8201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa33498 + "" + 5fc03971d7234498; + 29b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a + 22 + d334d7d0dd6b420b; + 260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22b + b02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2a + 51b4652c5715fba8; + ebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98 + ef1f0446b42fb144d44b6d00f06dc188d472a7 + c288ffba6c151611; + 84e0c6f21195a3b9f4ae985511265febd11c16 + "" + 2787117c93c78272; + 4720eef9eb1c8dd0b00951f284649016ed0045 + 63 + b9f64461b055f56d; + 31854bc78bf43966eb0cfa9138ddc399084456 + 08fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126 + dec9356cff25fd20; + b807e6daa089c3f9099c5ffb824173d7634c04 + 226f30cbb7f0e4a973a8cd190107314717a774 + f7be51b3498189d3; + 56f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9b + "" + 69b721838992f955; + c597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9c + e0 + 27583a3b6ce6eca6; + 21a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18c + bfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458 + 03e79dfa55f427b3; + cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957 + f4b03cf43e89957f9a3e8128f8743d16687b7b + 2eb16505976b0bf1; +} + +rc2-ocb3 { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268ee + ee533285a6ed + "" + "" + "" + 581f918026a62a86; + 810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1371206 + 34c9519848a8 + 77 + "" + "" + 0f2f73159c7260d2; + ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07d + f0591d8fa21f + "" + 2d + af + f64c74ec46bb90b1; + d88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3 + e98787 + "" + 31ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a8 + 055814531dcb494c81bdd40c6b320ac9cdf3f6b48b3e62ca + 9624c68017513bf7; + 94476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52 + ebfda19d0c + cc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33 + d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605f + 7dbbed27e29a669ee60e79d868848e797cf8d585fa877eef + b181420c050f46bb; + aee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600 + 157846b710ee + "" + 72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d + d2edbee66b1039b346ad18f087e5712227159fa306a398b03c5805ebaa + 7f3a208c993f1401; + 57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f + 768281e040a9 + b9a222bd689aef66f5306ceb0c6b08ac8b0a22 + 260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe836 + a7d224261bc9eed46f062bad5ce6acf20db49e5efa965da235a6cbfcf2 + 800f8ff9dbcbfcfb; + 8131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451 + dcd1af5813b7 + "" + "" + "" + abdbde1d369f81cf; + 0d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d + 00f06dc188d4 + 72 + "" + "" + 8a82cb9899ea8c5e; + a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717 + a77456f3ff66 + "" + 9c + e6 + 0d8c6497b6eae6d2; + 732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84c + ef64f6 + "" + c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b + 49ef16eee0810eecd3e8dab4f26ab52a367325b186d5829e + 1703b30f19f8fd57; + 7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1 + f5c054b2d9 + 83514605ec590294a319b9802068a9f891bc5ba5afabf8c3 + 122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d558 + 6d390ba093cfe6c87e7d319eb6aa78bad09fc27ef0901b6e + 44577228a64debfa; + 9bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a + 2e86041c1b9f + "" + c214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c3680 + 7c69cf94aeefeb59424b9cea58a906052733cd4218668705ab2853691c + e4f0891347b99255; + 0d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c4863 + 15799dc875fb + a578c8ec4837898a92142b5b0677da1ac27311 + 7b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d + 625cdc216187b9b9c5fa391d280bfa6b305ba1cb1fdd3724d8a72e1ac7 + 519207d1413a1b4d; + 380d2f9aaafe2dd721c0095c88088476892114 + 50ba8095ffab + "" + "" + "" + 06cfa98d411047e9; + 1eaadf66fd22ac1976063e113ab61f813e28a1 + 397a7974a1d7 + f4 + "" + "" + 175d23bbcafb83d7; + 220c785fe426a5a0e80f678d404147842941fe + effdc2eb44dc + "" + 8c + 58 + 5468b08a313669e1; + 0d5e8f444f7f4e0c893959b74dc23a7bb40e7e + 0013e5 + "" + 150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e + ad2f294aef829753411546662ae01fb4b8c949c124b4a49b + 6d43da0bc3eae79d; + 560475cff206877de69146acc3ab6cf8556b7a + a776945948 + d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391 + b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe6 + 52df344f60bb655ce1efadd2bd8aadb58cba837a06a85693 + dfd8c77383ca55f1; + 1e737882cd09c2b9a80f34c0fde11c2481b11f + c76bfa4dbf71 + "" + 0a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07 + 8be902be354731e8231299e1b2dedaae4690ecf8089199e6cec95b6123 + 0f45a8eb852e5baa; + 398a1458c2c6b61dbdbc1cccada8c1a0a9aabb + 6c4e3c3554f8 + fb1ef61614c270295dfc0ca6551ca4bdb75359 + f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cb + 3fb468bbadc6a29bd6281da179066d2ade7be03df9c6b383c8e8c13546 + b26515dac888c01c; + c0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c4 + 3f3df6c2b3fa + "" + "" + "" + 34bd44dbfedfadb7; + c7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53 + b3f3ebd66ddd + 98 + "" + "" + 30e8cb9e8b9c5270; + cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25 + d54756fa5c47 + "" + f1 + 0b + a2ccd20dc938026f; + 6f64b837bb4926214211a1c696ba172010abb433922a22d9fd8815 + 19165e + "" + b9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5 + 68cd0332b59dd009fe414fedbaa6e5db5617a72662f17e00 + e56e28e0835cfe53; + aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d + 64f2ed6a29 + b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3 + 001da597a1406d465b7b1419ea51cf858f938f6daafbd656 + 14eba6942ae06ed78cf099b84112f9a14ef047a66bc60759 + 8cf160f02394665d; + 445a09898eaa96ffc3d1d2e31e4e34c94b8bfae64825ecd75a66d8 + 8eedb969ffe0 + "" + 7669845ebb7a24c69f13d099f47166edf54538e88fbf433a7ff2120851 + 6d2c904a5679e677bb5388b0fd803942da8009ba69144d90adeebbbd9e + 9bc08b7a451dab64; + 79e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70d + da7a4ca2a25e + 771702fb1901ecfc8a959cb8e75079bb018ccc + 8c54f31b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c + 7e6523063d93c71b5e3843e7e1db47185be88cd6e59983a344ccaa55f3 + de2d08e85152d02e; +} + +rc2-ocb3-mct { + 16 cf8c7167477a5451; + 14 f7b6b2058ca5db46; + 12 249d762b7fef3e0a; + 10 a6d5f268d2dc063d; + 8 760827c7117d67ef; + 6 4acbb3854f8a4d2c; + 4 9165027bf9b60335; + 16 06ec3efc4156; + 14 0b3b19c5b0a6; + 12 8651074d6d12; + 10 f2c5ce719be9; + 8 d6646daf8e75; + 6 70c48ce7d192; + 4 61903ea2f3fe; + 16 a9049697; + 14 e4cdf5af; + 12 5571a44b; + 10 a9e735fa; + 8 4179cf26; + 6 4a83d2cf; + 4 f50be88c; +} diff --git a/symm/t/rc5 b/symm/t/rc5 index e7a02c96..77daa317 100644 --- a/symm/t/rc5 +++ b/symm/t/rc5 @@ -13,3 +13,933 @@ rc5 { dc49db1375a5584f6485b413b5f12baf 2f42b3b70369fc92 65c178b284d197cc; 5269f149d41ba0152497574d7f153125 65c178b284d197cc eb44e415da319824; } + +rc5-cmac { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057 + "" + daf5b15f8e1e563c; + acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed5415 + 4f + da179047660f232b; + 8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a + 96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b9 + 0bc5dfb1ac40f05c; + 7e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a8744 + 98ad0abef8bc4fcb70e27e98ef1f0446b42fb1 + ba244301c8380eac; + 44d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff677 + "" + 4c21b877018c36b9; + 8554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d1 + 7d + 3806f9d4de532103; + 4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c + 3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac8 + a23a44e7657e986c; + 61a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cf + f206877de69146acc3ab6cf8556b7aa7769459 + e4b7b2e862a7a773; + 48d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee475 + "" + f0b878ae4b245d7a; + 8a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e + 0c + 6f07948d34c807ed; + 536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1 + a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551c + 3b56f732d29bcda8; + a4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb2384 + 1da1ae8f4ae480cda98ad6cf2bacf6f9fd3f82 + 28c46ab756a75864; + 1330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f1 + "" + 08523dfcb089cd8c; + 6f64b837bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59c + c7 + 26a7e390109474a1; + 83443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae648 + 25ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099 + 841195a80291401c; + f47166edf54538e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8 + e9002926ad0284c738f4cb0f58a1e34c8b15ad + 029a65f6ecedeaec; +} + +rc5-ccm { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057 + acc876 + "" + "" + "" + 7c254f77; + 38f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28 + 523c03 + d4 + "" + "" + 1bee7cd9; + de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca3 + 38527e + "" + f1 + b4 + 2a4035c8; + 9b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa + 69a4cd5214 + 7ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f04 + 46b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9 + 27b471cdc900d7c1cecdbccbe0c791d0894881688285dc18 + 0c52bf2c8519e396; + f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021 + a5f1fa4ffa + 91544485f1a1258b2b9b8f0911e32d65cc1770 + a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948b + 4c97911b3e34ed74ca84d41573f434210e43911778a77caa1bb64b5d52 + 329a8ae6ba7b6150; + dd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a + 957eb6 + "" + "" + "" + 83c54227; + d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec81 + 6ac861 + a8 + "" + "" + d11cd472; + b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206 + 877de6 + "" + 91 + d7 + 75a2a5f9; + 46acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3 + fac7cbcf96 + 523d4723f91801325eb8553236651c96788d73d192ee53b3 + f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9 + 740ab29287b8db09e16309ab92186c430c2c71905ef788db + 16ed39d411395c7f; + b59ed034a867642d25d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e88fbf433a7ff212085179e79771f6eee7283a + b178ef2b80 + 0d7b969da05780ffc1ba78c70dda7a4ca2a25e + 771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e900 + b630304c8082405cd416ec56b4b32cd188cb81075a1df8e7ded7042e84 + 15c392aa9df0ff73; + 2926ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb84241986c251f5b70be2367f0472 + 65264e + "" + "" + "" + 5c63c12d; + 0da72efe8995e6c932a17eab511eddb8e4ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961 + dcfd40 + 08 + "" + "" + 8ec0a5a4; + 8d5be74088e4097efb0368c7e2f431ee6988cf2a0e9ebeb3de79c4f86c9e4fba61339d6d907eab + 7707ca + "" + 48 + 61 + d74da629; + ff5ba1ae93d16225d469de5747bc1addf5748729720a320fe14fd29cfc59314fe2079c0a2535de + d56112d6e3 + d33dcf7c71cd7d130323794e3da84a9df69703a9caf02d2a + 8f57ac71e554a6850d55882f8c7ae6994fc8528bd18c374f + 12ebdfc275cb1ad1926629dec9765ecde238384b6b77aed3 + 91dd4e2e2acf63f7; + c43581d2f72a89584a2404a059f7f99c7241a0c879d6d4455b382a9ce757b3e7a1d07585ad9d7e + a9c7c9cf54 + f3bc6d94238ab56d738e02abd651477cd726d6 + f3ebcd6fadeab50906642a7de6496247060e7be3632ed9bd94bb42f45a + a0cbde9a036ed8857dec5ad4dce61b29ec4a9c304fe386afefe3aee97f + 84fbd4d0f0710fea; + 8733b2cd2df9d1d905cfdb29983050d6bcdb686a0c897031ad09a5b8fa687ec3bad8e18dc2ad361f1e226e78876cd35f86c639733c5cd84aed8aaebabb7e0f24edfd9710b7bca91b612ea37fc5 + cc09f7 + "" + "" + "" + b8580130; + f62f66b423fcd2dec5de24d264f2c839839c1b06319f687dbc68d9f07fd41ccb4f8cde8de201ec2680332bbded4883deea0b58b54bdd13c17ef292b0ded3caeb5e57fd21df10bc6186265ee6ea + 45907d + e6 + "" + "" + aa6fedbc; + cb822fb2ef953aea358a03e0fce2e1b9511bd332c86e67f123377a8f0256b8dcc73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7496993a25b072945d83f923e66b0a6689cf0969c00 + 3a8fca + "" + 80 + b5 + 0b3d21e2; + e322a4b1bf050c1220450433efb6b6d8a2d820cf27a64b9d47f636845dac557bb3e75f3a18fb8e173416867fcd0ee78ddd9236beec76d55ed58b10f91d07a037791ab96e83c4bf2fb5b205e592 + c172a5cbc1 + 9456c95c1bea6079f3867e52d663cb3884b2a0a8ff825df7 + 52423f3179bfeb89eca385f20ddce5f1f23564672e370ffc + 704a2f85040f89ae682fc9fe222d1514c8a6ee4c83621978 + bd37c7f24ffd34dd; + 37d400a31e8aac1d426ce10df73c5ee478b3b63d91024780e974a8a2a0e7a36f84ab1286b627e7d01b38a84a6de738721ed80fd0d7f69fa658abb5a440d304128719b541a9451cead18e4c61d9 + 3d1f8fcc53 + 574427767396322b3bf7d02cec05093696cec0 + 7591ada462271b1d1519eedde0df37a330fe8c22ebd77705917b7e32ae + a81b6872abcb10bf73091054448aa06f5713d2da96a21467a86272aae7 + 3acb5a6ac60a7d69; +} + +rc5-eax { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057 + "" + "" + "" + "" + b6a3c65665d9698f; + acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed5415 + 4f + "" + "" + "" + 28e0ed64beb3636e; + 8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a + "" + 96 + "" + "" + 4e86273646b6d548; + ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b9 + "" + "" + 70 + e2 + b61886a4345f760a; + e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107 + 314717a77456f3ff + 669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9b + c597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc + c1032a72ac5e8845a7d27deae33795ccc3bf3caf3e3cb94d + ac40d28502442851; + 0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf + 9a05c7efedef34 + 01539c51d2a90bbf7f1bfc338ab0ef5746ea8f + dcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2 + bf3cf0b9900f40e42643c19226af6cff9d221051ab7a52e22bdb0343d0 + 19e314d1c9556ec7; + d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261 + "" + "" + "" + "" + 3c01672989b90b3d; + b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147 + 84 + "" + "" + "" + ec812e10e0061171; + 2941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551c + "" + a4 + "" + "" + f87f9705308d2757; + bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b9 + "" + "" + 68 + 2c + ecb3af42ad5aaf5c; + 56beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb84241986c251f5b70be2367f047265264e0da72efe8995e6c932 + a17eab511eddb8e4 + ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd + 40088d5be74088e4097efb0368c7e2f431ee6988cf2a0e9e + 097489eca92aa5642b549cfac254a0084e6392328b287f68 + 1e35efa371fa0754; + beb3de79c4f86c9e4fba61339d6d907eab7707ca48ff5ba1ae93d16225d469de5747bc1addf5748729720a320fe14fd29cfc59314fe2079c0a2535ded56112d6e3d33dcf7c71cd7d130323794e3da84a9df69703a9caf02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd18c374fc43581d2f72a89584a2404a059f7f99c7241a0c879d6d4455b382a9ce757b3e7a1d07585ad9d7ea9c7c9cf54f3bc6d94238ab56d738e02abd651477cd726d6f3ebcd6fadeab50906642a7de6496247060e7be3632ed9bd94bb42f45a8733b2cd2df9d1d905cfdb29983050d6 + bcdb686a0c8970 + 31ad09a5b8fa687ec3bad8e18dc2ad361f1e22 + 6e78876cd35f86c639733c5cd84aed8aaebabb7e0f24edfd9710b7bca9 + faaae6078a435e40c355d6cb7522b57d1d2041d016be50c0499a94a4c9 + d37dacc2ee37665c; + 1b612ea37fc5cc09f7f62f66b423fcd2dec5de24d264f2c839839c1b06319f687dbc68d9f07fd4 + "" + "" + "" + "" + 8e0d69b365dcd5f0; + 1ccb4f8cde8de201ec2680332bbded4883deea0b58b54bdd13c17ef292b0ded3caeb5e57fd21df + 10 + "" + "" + "" + 70b4543f8437c930; + bc6186265ee6ea45907de6cb822fb2ef953aea358a03e0fce2e1b9511bd332c86e67f123377a8f + "" + 02 + "" + "" + 7b962a2f0a36c218; + 56b8dcc73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7496993a25b072945d83f923e + "" + "" + 66 + d3 + e3934e8cf3dd1e43; + b0a6689cf0969c003a8fca80e322a4b1bf050c1220450433efb6b6d8a2d820cf27a64b9d47f636 + 845dac557bb3e75f + 3a18fb8e173416867fcd0ee78ddd9236beec76d55ed58b10 + f91d07a037791ab96e83c4bf2fb5b205e592c172a5cbc194 + 1c11e3e723c447062953918da6c2935a8f736ba211e02110 + 26cf3b89bb9216cc; + 56c95c1bea6079f3867e52d663cb3884b2a0a8ff825df752423f3179bfeb89eca385f20ddce5f1 + f23564672e370f + fc37d400a31e8aac1d426ce10df73c5ee478b3 + b63d91024780e974a8a2a0e7a36f84ab1286b627e7d01b38a84a6de738 + 76d660c82fe87ec1fe0ae671550a17ecff0c9e771db2949c1b786f1cf2 + 740fccf37358c969; + 721ed80fd0d7f69fa658abb5a440d304128719b541a9451cead18e4c61d93d1f8fcc53574427767396322b3bf7d02cec05093696cec07591ada462271b1d1519eedde0df37a330fe8c22ebd777 + "" + "" + "" + "" + cfff0e086dd13bf8; + 05917b7e32ae88f45a34a8ba3037235e19a394be4d26ce47317d8087684456b4cfc5555e925e3e7b2ebc829b2d0505ea617b0ca9531bcdb96040d39040e632d562643ccb64286303040fcaf679 + e9 + "" + "" + "" + 1e93f551fac620d8; + 14eaddc05af8843ce6a427b99a5dc266de31c09165237eeefe4b58cc034b9f099f04678c2a9da898b39324cd3087a651014f6796f9c4881d89e127e62221e47e57badd678d490c2f320ff8fb1c + "" + 42 + "" + "" + ea6e9288b9febdb3; + 761bd439f3e96dc0ed1d5b2169912af1a4e2c533c52ba3e8c71c23a089e231480aa63c484fb34bd522397f102cb8ecf4f64e329884fe73be257a753b38200bc23f94a079bde2dd98d813655daf + "" + "" + a1 + 83 + 409170cbacd6adbb; + 5b85419d15c41a5153cce5d0e8c8702db2ba11927589678d4f7b8fcfad4818c411f15f452300903874f9a532ee46496ae753a2340af7b91f9632fc5ae71ae18b40de751ab6b6761ca16434a993 + 5e466e11c1cb072f + 32a59c313dba3db646ae909a096697d9a7b0556463ff1126 + ebc43263391424d02739d0787e804d8f1dccf6c897a8a484 + c9f82dea0b1b5fd479b0aeb37b717817455887a199312aa9 + 4e1d9e542a78d512; + 31324324041b5302ccd501b538bd03d5cb5c90d1fd3f7d2be187a787032c79ed900764ee4ce1d3fc042c084f7d8c0c48ad7d6f1eabd0fd1ec24a88f26734d5c8d92dbd873a8fe113090d401bea + 4d28ff49f10ff5 + 93adc258e091abd31b62dd1735158f98765970 + acc6602da063aae01a2a199d3a4f37a5f062d216d2053a83b5d3a0488a + a9dc22dc5d57626720b7c1260c63dae59cbad790ac527d5a26e7d943dd + 86f8915e2fdee1e3; +} + +rc5-gcm { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057 + "" + "" + "" + "" + e2f61b7a5d2e1c0a; + acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed5415 + 4f + "" + "" + "" + 8054b24c29fed688; + 8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a + "" + 96 + "" + "" + db8e85bf23f737de; + ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b9 + "" + "" + 70 + 17 + 7c5e0036fc6b0768; + e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107 + 314717a77456f3ff + 669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9b + c597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc + 3549c431f3e7576dfcaf3130ec16f3f548704d727782677b + 28148be1172ee6bf; + 0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf + 9a05c7ef + edef3401539c51d2a90bbf + 7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add + 3ff03565f741b63e12a647f755353af479b9f3ddfa1d50ff1540221f0bbb5c8b1e + 81f81acac5371be7; + 9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea1 + 2ff4bb5f069b8a + 2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e + 740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523 + b0b28a3e099aecdda0b6756d2340184ab16df2c8cee22003ec3b783500 + 61d50b3d4e61fa34; + bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f + "" + "" + "" + "" + 6133d10511794867; + 678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c27029 + 5d + "" + "" + "" + 25ff252aec8e0979; + fc0ca6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d + "" + 64 + "" + "" + 68c3eb5a75e3992e; + f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb84241986c251f5b70be2367f047265264e0da72e + "" + "" + fe + ca + 187921ec9e1052c1; + 8995e6c932a17eab511eddb8e4ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd40088d5be74088e4097efb0368c7e2f431ee6988cf2a0e9ebeb3de79c4f86c9e4fba61339d6d907eab7707ca48ff5ba1ae93d16225d469de5747bc1addf5748729720a320fe14fd29cfc59314fe2079c0a2535ded56112d6e3d33dcf7c71cd7d130323794e3da84a9df69703a9caf02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd18c374fc43581d2f72a89584a2404a059f7f99c7241a0c879d6d4455b382a9ce757b3e7a1d07585ad9d7ea9c7c9cf54f3bc6d + 94238ab56d738e02 + abd651477cd726d6f3ebcd6fadeab50906642a7de6496247 + 060e7be3632ed9bd94bb42f45a8733b2cd2df9d1d905cfdb + ce458e557a153a69bff6fe3c4489c7a06e87dbbe31777fb2 + b90acc3a3f31e693; + 29983050d6bcdb686a0c897031ad09a5b8fa687ec3bad8e18dc2ad361f1e226e78876cd35f86c639733c5cd84aed8aaebabb7e0f24edfd9710b7bca91b612ea37fc5cc09f7f62f66b423fcd2dec5de24d264f2c839839c1b06319f687dbc68d9f07fd41ccb4f8cde8de201ec2680332bbded4883deea0b58b54bdd13c17ef292b0ded3caeb5e57fd21df10bc6186265ee6ea45907de6cb822fb2ef953aea358a03e0fce2e1b9511bd332c86e67f123377a8f0256b8dcc73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7496993a25b072945d83f923e66b0a6 + 689cf096 + 9c003a8fca80e322a4b1bf + 050c1220450433efb6b6d8a2d820cf27a64b9d47f636845dac557bb3e75f3a18fb + 17a5e823d237aa01c73f6414d39d44b2f564a0dd3f1a07a2899a8051d1f0df8f39 + 36f636bbcbf9dd90; + 8e173416867fcd0ee78ddd9236beec76d55ed58b10f91d07a037791ab96e83c4bf2fb5b205e592c172a5cbc19456c95c1bea6079f3867e52d663cb3884b2a0a8ff825df752423f3179bfeb89eca385f20ddce5f1f23564672e370ffc37d400a31e8aac1d426ce10df73c5ee478b3b63d91024780e974a8a2a0e7a36f84ab1286b627e7d01b38a84a6de738721ed80fd0d7f69fa658abb5a440d304128719b541a9451cead18e4c61d93d1f8fcc53574427767396322b3bf7d02cec05093696cec07591ada462271b1d1519eedde0df37a330fe8c22ebd77705917b7e32 + ae88f45a34a8ba + 3037235e19a394be4d26ce47317d8087684456 + b4cfc5555e925e3e7b2ebc829b2d0505ea617b0ca9531bcdb96040d390 + 57f5a0f8d6415a8a621157e06114338900a5cd0837278b2751fc96da0d + 5e3bc104eafa8f9c; + 40e632d562643ccb64286303040fcaf679e914eaddc05af8843ce6a427b99a5dc266de31c09165 + "" + "" + "" + "" + 7810963d0383460c; + 237eeefe4b58cc034b9f099f04678c2a9da898b39324cd3087a651014f6796f9c4881d89e127e6 + 22 + "" + "" + "" + 914c0d07b56a620c; + 21e47e57badd678d490c2f320ff8fb1c42761bd439f3e96dc0ed1d5b2169912af1a4e2c533c52b + "" + a3 + "" + "" + 841a2c9697997e1f; + e8c71c23a089e231480aa63c484fb34bd522397f102cb8ecf4f64e329884fe73be257a753b3820 + "" + "" + 0b + 05 + 8137867eb2cf4281; + c23f94a079bde2dd98d813655dafa15b85419d15c41a5153cce5d0e8c8702db2ba11927589678d + 4f7b8fcfad4818c4 + 11f15f452300903874f9a532ee46496ae753a2340af7b91f + 9632fc5ae71ae18b40de751ab6b6761ca16434a9935e466e + 38b42c255ef96643eb10b3bc9f2691c2e99fce686f1f475b + c32a64eb29ba1822; + 11c1cb072f32a59c313dba3db646ae909a096697d9a7b0556463ff1126ebc43263391424d02739 + d0787e80 + 4d8f1dccf6c897a8a48431 + 324324041b5302ccd501b538bd03d5cb5c90d1fd3f7d2be187a787032c79ed9007 + 181bd0dc71010e424ebc9ef3076822ee1f476f71597408a6bed166e9d1041c5144 + 4752f2416b0d0b58; + 64ee4ce1d3fc042c084f7d8c0c48ad7d6f1eabd0fd1ec24a88f26734d5c8d92dbd873a8fe11309 + 0d401bea4d28ff + 49f10ff593adc258e091abd31b62dd1735158f + 98765970acc6602da063aae01a2a199d3a4f37a5f062d216d2053a83b5 + 80090c15eefaee5a89856fb9a6e0d3754984998915327ea69facb3c3e5 + 67af4d834f3cdf11; + d3a0488ab0d2df631b2892cdfcf9fdd0f37de9ed67179aeae82fe00009428b297b553230a6d917fa0c1a233c9ebc8a4cba45b20543c540fc1b9dbce078b87a1534acf03897b95a3f372e9f6c5a + "" + "" + "" + "" + 2f94915a82b486df; + 5f2ae44a7dbce9ba43a39089de20de70d0544b5151db0a16e9769e8f2fc12c7f839fab269a0056284a697ffd4113a1cf43b5d5bdce2d86dead83f5a356e9106bedf908db61f1119f9700260ea9 + 37 + "" + "" + "" + f02d5d46eab2e377; + 9cc7232184d217158fee8ca42e75614739e9007f234fbcd86b0ad8f641a0449b6d9b0f99d1cb4a57a4d6f987feb0ade90aa1d81c4f497b3734be301da3e25fe692629db57311f422f3a1573f9e + "" + 05 + "" + "" + e3c6faf9bbec6f8a; + 53a23e96265e4326fa532d7136863e5b4bc6c99ade3d4eb23cacdf6e42ad8ca13187eba1532920ba31582b3793b05fa65e9f80c5814b91f4d3c581c7b16c46b484859c6d19eebaf124681aa3be + "" + "" + 99 + 50 + 8e188c981fa9757d; + 43307fa4ef095ef8e7e50b703dc0420e74227c9351366ef8e98e1e24b48aa989dbb8d0f10471ae5428a6012fbe4f5cb2dab2863e574842cc0b3774e00dcfa63b0db1716c7e916a26fc2e198f8d + b63ab59955989497 + 782f16c5816270ef3fbe4ea22f484ddc12ec8f4bdbd6ebdf + bafb21fcf5427dbee5f95b53a0b4cb6d7c128b79f4657895 + 4a73ab00c6b33f577e36b151435331661e7a4f8ad2cf2424 + 3feaf9765a80ad6d; + f4b0ba518dd61436140f20d40224baac3a602da83cb254a7e03f052c63c1f3f00f301cc944a1789133bb8048f07dc123f2ca7e20c83988e4bfea6d561ab5aea542db544a14376d5d52f7265c7a + 8d2fc4fe + ef99b9dba89eb472f71d8e + b5affe900d776e4cf74e52b6c86db981143082735c6473a86a5da3d2e8cbb8602e + f41bd01dcd02e66f0d3b4771c32053d11c302c6144fb40397bf548b21d6b748655 + c0c9b188065fbe55; + bbaf08bf9315fba15f46714bfd2c8312fb5744dfe84615ddb93f15360161f2efb1fc39b8b6ad97427dcaa0435bee7f3a5c11fd01b9c120aa6004f84bcba838a1c33beb4087719135b355dce9ff + d6fd639f192e4c + 2c9a2752bf74a3f63408d3b27df51f44ed5537 + bfb0162f05edbad1b2c36ceec1dc407475b8e05fcb5ee66c7205f21804 + 7a28b08624230f3c25eac43abc77e6525efd4ccf45b72033af74c47021 + 70cf57e5e7d02c97; +} + +rc5-ocb1 { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057 + acc87638f5080467 + "" + "" + "" + aa54e91505bc3ec6; + 33d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de + 1600157846b710ee + 72 + "" + "" + 5e23eb9cc063fb52; + 807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f + 88de9fd41e72d7b9 + "" + 7e + 14 + 8086d6e7472314d3; + 23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498 + ad0abef8bc4fcb70 + "" + e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0 + ace115dc9234795ceda92323b7555d9b7088d5f03851f5a8 + ad07550f521cb01d; + c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003 + cc0cae9ce021a5f1 + fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18c + bfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458 + 9ef4ec1d3bd29e3da733811d8d32183a38e0c77c4fa209f4 + e2244052d820e90f; + cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2 + d983514605ec5902 + "" + 94a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d + 568ebf6a8b3c3aa4bb11dfe4794a9b2dce157fc51ea99119a0b680fba6 + a7720c81e5980c76; + 4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d96 + 45563a308ba60076 + 817523bd2abf1261b089d8f23a9c2835076a23 + faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973ac + b3118f057e88cb0db02cdb8fac8f78723937c596e56beeda7f56cc4098 + 90496eb2b1214b4c; + cd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43 + a15a84e81d7f5ced + "" + "" + "" + c80dc735b4b0d91c; + aa49e2414ebf47970e560475cff206877de69146acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cd + a98ad6cf2bacf6f9 + fd + "" + "" + e90954047fa57813; + 3f821330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ff + c3d1d2e31e4e34c9 + "" + 4b + b5 + baf615ac4d6842ea; + 8bfae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb84241986c251f5b70be2367f047265264e0da72efe8995e6c932a17eab511eddb8e4ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd40088d5be74088e4097efb0368c7e2f431ee6988cf2a0e9ebeb3de79c4f86c + 9e4fba61339d6d90 + "" + 7eab7707ca48ff5ba1ae93d16225d469de5747bc1addf574 + 757d492944cb37a370da05afd0734e35c6bc4a0f970843ed + 33e2b21461d5dd3d; + 8729720a320fe14fd29cfc59314fe2079c0a2535ded56112d6e3d33dcf7c71cd7d130323794e3da84a9df69703a9caf02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd18c374fc43581d2f72a89584a2404a059f7f99c7241a0c879d6d4455b382a9ce757b3e7a1d07585ad9d7ea9c7c9cf54f3bc6d94238ab56d738e02abd651477cd726d6f3ebcd6fadeab50906642a7de6496247060e7be3632ed9bd94bb42f45a8733b2cd2df9d1d905cfdb29983050d6bcdb686a0c897031ad09a5b8fa687ec3bad8e18dc2ad361f1e226e78876cd35f86c639733c5cd8 + 4aed8aaebabb7e0f + 24edfd9710b7bca91b612ea37fc5cc09f7f62f66b423fcd2 + dec5de24d264f2c839839c1b06319f687dbc68d9f07fd41c + aefcbff3659b393a7cf6952eb2fd4ad464d1be5c0c13b79b + 1ba057a604a1b599; + cb4f8cde8de201ec2680332bbded4883deea0b58b54bdd13c17ef292b0ded3caeb5e57fd21df10bc6186265ee6ea45907de6cb822fb2ef953aea358a03e0fce2e1b9511bd332c86e67f123377a8f0256b8dcc73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7496993a25b072945d83f923e66b0a6689cf0969c003a8fca80e322a4b1bf050c1220450433efb6b6d8a2d820cf27a64b9d47f636845dac557bb3e75f3a18fb8e173416867fcd0ee78ddd9236beec76d55ed58b10f91d07a037791ab96e83c4bf2fb5b205e592c172a5cbc19456c95c1bea6079 + f3867e52d663cb38 + "" + 84b2a0a8ff825df752423f3179bfeb89eca385f20ddce5f1f23564672e + 19b818cf69f0e92cd5a9f539f91e73dc543141acde903d98a24e1234c8 + a41bbb9bbe7c82db; + 370ffc37d400a31e8aac1d426ce10df73c5ee478b3b63d91024780e974a8a2a0e7a36f84ab1286b627e7d01b38a84a6de738721ed80fd0d7f69fa658abb5a440d304128719b541a9451cead18e4c61d93d1f8fcc53574427767396322b3bf7d02cec05093696cec07591ada462271b1d1519eedde0df37a330fe8c22ebd77705917b7e32ae88f45a34a8ba3037235e19a394be4d26ce47317d8087684456b4cfc5555e925e3e7b2ebc829b2d0505ea617b0ca9531bcdb96040d39040e632d562643ccb64286303040fcaf679e914eaddc05af8843ce6a427b99a5dc266 + de31c09165237eee + fe4b58cc034b9f099f04678c2a9da898b39324 + cd3087a651014f6796f9c4881d89e127e62221e47e57badd678d490c2f + f2bc32f9e6d98d55aa5631671de574e5b6e0e0e17a59f20f418d3555f8 + 6a92cb246769b913; + 320ff8fb1c42761bd439f3e96dc0ed1d5b2169912af1a4e2c533c52ba3e8c71c23a089e231480a + a63c484fb34bd522 + "" + "" + "" + 6dcc9a87c6b58479; + 397f102cb8ecf4f64e329884fe73be257a753b38200bc23f94a079bde2dd98d813655dafa15b85 + 419d15c41a5153cc + e5 + "" + "" + 62692c7d1e45c739; + d0e8c8702db2ba11927589678d4f7b8fcfad4818c411f15f452300903874f9a532ee46496ae753 + a2340af7b91f9632 + "" + fc + e3 + bd2bbcb67cb7a71b; + 5ae71ae18b40de751ab6b6761ca16434a9935e466e11c1cb072f32a59c313dba3db646ae909a09 + 6697d9a7b0556463 + "" + ff1126ebc43263391424d02739d0787e804d8f1dccf6c897 + 4a7b3da4e48db3ad461bce3fa4e1eb8bfe3d5415b80884f8 + e8e7fdcdb5bd4809; + a8a48431324324041b5302ccd501b538bd03d5cb5c90d1fd3f7d2be187a787032c79ed900764ee + 4ce1d3fc042c084f + 7d8c0c48ad7d6f1eabd0fd1ec24a88f26734d5c8d92dbd87 + 3a8fe113090d401bea4d28ff49f10ff593adc258e091abd3 + 7f77bf26d0ccc5527ce3a51a3802d09ea7817507df9dbaeb + 64cd828bd8c60820; + 1b62dd1735158f98765970acc6602da063aae01a2a199d3a4f37a5f062d216d2053a83b5d3a048 + 8ab0d2df631b2892 + "" + cdfcf9fdd0f37de9ed67179aeae82fe00009428b297b553230a6d917fa + 220fc76c73b6b558f327d88b2ceb3c28b23e09ab5b15757d041a66548f + 99c4bfbe566dbede; + 0c1a233c9ebc8a4cba45b20543c540fc1b9dbce078b87a1534acf03897b95a3f372e9f6c5a5f2a + e44a7dbce9ba43a3 + 9089de20de70d0544b5151db0a16e9769e8f2f + c12c7f839fab269a0056284a697ffd4113a1cf43b5d5bdce2d86dead83 + 129f452d3b69b5c33ce6507970c4f36352a7c4bf4e3d621185fa8ef09a + c7267b667c9d44bd; + f5a356e9106bedf908db61f1119f9700260ea9379cc7232184d217158fee8ca42e75614739e9007f234fbcd86b0ad8f641a0449b6d9b0f99d1cb4a57a4d6f987feb0ade90aa1d81c4f497b3734 + be301da3e25fe692 + "" + "" + "" + d59834fe604f12e2; + 629db57311f422f3a1573f9e0553a23e96265e4326fa532d7136863e5b4bc6c99ade3d4eb23cacdf6e42ad8ca13187eba1532920ba31582b3793b05fa65e9f80c5814b91f4d3c581c7b16c46b4 + 84859c6d19eebaf1 + 24 + "" + "" + 0c9a3b106bc9bca6; + 681aa3be9943307fa4ef095ef8e7e50b703dc0420e74227c9351366ef8e98e1e24b48aa989dbb8d0f10471ae5428a6012fbe4f5cb2dab2863e574842cc0b3774e00dcfa63b0db1716c7e916a26 + fc2e198f8db63ab5 + "" + 99 + 87 + 2b28f9babe659513; + 55989497782f16c5816270ef3fbe4ea22f484ddc12ec8f4bdbd6ebdfbafb21fcf5427dbee5f95b53a0b4cb6d7c128b79f4657895f4b0ba518dd61436140f20d40224baac3a602da83cb254a7e0 + 3f052c63c1f3f00f + "" + 301cc944a1789133bb8048f07dc123f2ca7e20c83988e4bf + 8be72ebd52cb194d6b0e4fc423bb898f655d938d11985432 + 0564db4049183242; + ea6d561ab5aea542db544a14376d5d52f7265c7a8d2fc4feef99b9dba89eb472f71d8eb5affe900d776e4cf74e52b6c86db981143082735c6473a86a5da3d2e8cbb8602ebbaf08bf9315fba15f + 46714bfd2c8312fb + 5744dfe84615ddb93f15360161f2efb1fc39b8b6ad97427d + caa0435bee7f3a5c11fd01b9c120aa6004f84bcba838a1c3 + 49ac4c21db7bcf9453e935aadb85d304afe6fa4bb10002a0 + 9a90ed7bab6f9d86; + 3beb4087719135b355dce9ffd6fd639f192e4c2c9a2752bf74a3f63408d3b27df51f44ed5537bfb0162f05edbad1b2c36ceec1dc407475b8e05fcb5ee66c7205f21804c3b73451dc9a3aed7667 + c6342c8355ff66b9 + "" + 1eeffa115cf118eef301f2c93fda303878f7987116dba62d93a7da7027 + a3c938b621c4032adbd7b5bfeedff1eaa471ddefb2f396290902c00d59 + d682d2ff660fa862; + 4ffe5a6506e4e1439de76cc9d332ab03510df3c7d35dc526b5b7785400f53d34b5d55fcac5fbeadd81456bbe6bcedb015be40bfbda656483b32fc4d0a9dc2d7a68b134919d79de5268d7d2ce37 + 2a8a386aa718d09e + 19612f3d10fe569863bbd3ad42903905058b93 + 4eb213aa037de4e26cd4ceff7490353b5e7621d67ee3ddfb2584e1e12d + c494267b5ee0e2bd32b3c4e93b70ddfef6985a4d8360ed32e45209192f + 32e85181b5d1d655; +} + +rc5-pmac1 { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057 + "" + 25f3e24d8ae10215; + acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed5415 + 4f + f7da3d0334f4ad55; + 8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a + 96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b9 + 5d24a4c29b90fa71; + 7e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a8744 + 98ad0abef8bc4fcb70e27e98ef1f0446b42fb1 + ca50a7dd104238aa; + 44d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff677 + "" + dfde25eb32b74a23; + 8554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d1 + 7d + 58afcfd1b2ec5cca; + 4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c + 3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac8 + 3a50ecc246becae2; + 61a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cf + f206877de69146acc3ab6cf8556b7aa7769459 + ce6c1f810be61bf6; + 48d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee475 + "" + 497b2f55a33bed03; + 8a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e + 0c + 616706b07020fd1b; + 536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1 + a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551c + af712aca3c532277; + a4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb2384 + 1da1ae8f4ae480cda98ad6cf2bacf6f9fd3f82 + d47974ebfc5228ef; + 1330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f1 + "" + ee84e75847026484; + 6f64b837bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59c + c7 + 5605efcbb6e07489; + 83443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae648 + 25ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099 + 6182d51653af224a; + f47166edf54538e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8 + e9002926ad0284c738f4cb0f58a1e34c8b15ad + 27da50a416aca31c; +} + +rc5-ocb3 { + 60d7bcda163547d348b7551195e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057 + acc87638f508 + "" + "" + "" + 063c1bf330553d8c; + 046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03 + d4de16001578 + 46 + "" + "" + b6a770d618bfc1d7; + b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09 + c063c46f88de + "" + 9f + 74 + 570a5073b8afc17f; + d41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca9 + 86981a + "" + 874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b + fa80154a33c295155643798240fd22d30613b2b6770a3327 + 31aca92d9606f720; + 6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc + 69f6a9f2c0 + 945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a125 + 8b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554ac + afeb6335d22d91e6027e219981fa6d22fa23d4170ee22c35 + 09e60a6bdcc1ba7f; + f1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107 + c8e7d715a92a + "" + dd9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5 + f29328c6d4104e0e1ef80cd7494957aad54f69ae2d1b95e1421c03f769 + 7d433a869031bf7e; + afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740d + a967828e3604 + b35b15ffaa6c36800d9645563a308ba6007681 + 7523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a833 + d403996de8929a47a908bee11ffacc01a85f3d7af8c78ec0094a83e2ea + 10a662f856acdb4a; + 1f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959 + b74dc23a7bb4 + "" + "" + "" + 4fa9e8d71758235e; + 0e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d3 + 1f06a1dd5982 + cb + "" + "" + bba7bb90cb237373; + c0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b + 1419ea51cf85 + "" + 8f + fe + e5476d3424c2d40f; + 938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb84241986c251f5b70be2367f047265264e0da72efe8995e6c932a17eab511eddb8e4ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd40088d5be74088 + e4097e + "" + fb0368c7e2f431ee6988cf2a0e9ebeb3de79c4f86c9e4fba + 828b48b63905d7d298cf4f88d099cc209fe7483985517503 + 6bd18f02c7a6c90e; + 61339d6d907eab7707ca48ff5ba1ae93d16225d469de5747bc1addf5748729720a320fe14fd29cfc59314fe2079c0a2535ded56112d6e3d33dcf7c71cd7d130323794e3da84a9df69703a9caf02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd18c374fc43581d2f72a89584a2404a059f7f99c7241a0c879d6d4455b382a9ce757b3e7a1d07585ad9d7ea9c7c9cf54f3bc6d94238ab56d738e02abd651477cd726d6f3ebcd6fadeab50906642a7de6496247060e7be3632ed9bd94bb42f45a8733b2cd2df9d1d905cfdb29983050d6bcdb686a0c897031ad09 + a5b8fa687e + c3bad8e18dc2ad361f1e226e78876cd35f86c639733c5cd8 + 4aed8aaebabb7e0f24edfd9710b7bca91b612ea37fc5cc09 + 0089fb21527fed153e81acdc9229d8341ca36df6ebdada9b + cc5b59ffe07eaff8; + f7f62f66b423fcd2dec5de24d264f2c839839c1b06319f687dbc68d9f07fd41ccb4f8cde8de201ec2680332bbded4883deea0b58b54bdd13c17ef292b0ded3caeb5e57fd21df10bc6186265ee6ea45907de6cb822fb2ef953aea358a03e0fce2e1b9511bd332c86e67f123377a8f0256b8dcc73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7496993a25b072945d83f923e66b0a6689cf0969c003a8fca80e322a4b1bf050c1220450433efb6b6d8a2d820cf27a64b9d47f636845dac557bb3e75f3a18fb8e173416867fcd0ee78ddd9236beec76d55ed58b + 10f91d07a037 + "" + 791ab96e83c4bf2fb5b205e592c172a5cbc19456c95c1bea6079f3867e + 0853cf3d4515b9e4b005c95fdddf3c74d4d3ccdaaa1015ae379b550302 + 2a56e4bba5f8d187; + 52d663cb3884b2a0a8ff825df752423f3179bfeb89eca385f20ddce5f1f23564672e370ffc37d400a31e8aac1d426ce10df73c5ee478b3b63d91024780e974a8a2a0e7a36f84ab1286b627e7d01b38a84a6de738721ed80fd0d7f69fa658abb5a440d304128719b541a9451cead18e4c61d93d1f8fcc53574427767396322b3bf7d02cec05093696cec07591ada462271b1d1519eedde0df37a330fe8c22ebd77705917b7e32ae88f45a34a8ba3037235e19a394be4d26ce47317d8087684456b4cfc5555e925e3e7b2ebc829b2d0505ea617b0ca9531bcdb96040d390 + 40e632d56264 + 3ccb64286303040fcaf679e914eaddc05af884 + 3ce6a427b99a5dc266de31c09165237eeefe4b58cc034b9f099f04678c + 48d32eec290f067c12f81697153f4030c56b1b79ffe695bc972ffda584 + 15d05287d12f9c8f; + 2a9da898b39324cd3087a651014f6796f9c4881d89e127e62221e47e57badd678d490c2f320ff8 + fb1c42761bd4 + "" + "" + "" + 19796de26b769f5b; + 39f3e96dc0ed1d5b2169912af1a4e2c533c52ba3e8c71c23a089e231480aa63c484fb34bd52239 + 7f102cb8ecf4 + f6 + "" + "" + 22f17895a971f1f3; + 4e329884fe73be257a753b38200bc23f94a079bde2dd98d813655dafa15b85419d15c41a5153cc + e5d0e8c8702d + "" + b2 + 6f + 511d62bc5b29da6c; + ba11927589678d4f7b8fcfad4818c411f15f452300903874f9a532ee46496ae753a2340af7b91f + 9632fc + "" + 5ae71ae18b40de751ab6b6761ca16434a9935e466e11c1cb + a60bb59c8292e00486962cb216e756dd66613fe9569e549d + ed2836258e0dfe45; + 072f32a59c313dba3db646ae909a096697d9a7b0556463ff1126ebc43263391424d02739d0787e + 804d8f1dcc + f6c897a8a48431324324041b5302ccd501b538bd03d5cb5c + 90d1fd3f7d2be187a787032c79ed900764ee4ce1d3fc042c + 84e43f8b78a4b759d7832084f4a43b94380155ead68222cf + 53e98d05afc28fb5; + 084f7d8c0c48ad7d6f1eabd0fd1ec24a88f26734d5c8d92dbd873a8fe113090d401bea4d28ff49 + f10ff593adc2 + "" + 58e091abd31b62dd1735158f98765970acc6602da063aae01a2a199d3a + ccad9333e858aba3b6be61d2821fc6485b94dee4fd3da0f24e18c5c8eb + befad9a49693a9ff; + 4f37a5f062d216d2053a83b5d3a0488ab0d2df631b2892cdfcf9fdd0f37de9ed67179aeae82fe0 + 0009428b297b + 553230a6d917fa0c1a233c9ebc8a4cba45b205 + 43c540fc1b9dbce078b87a1534acf03897b95a3f372e9f6c5a5f2ae44a + d4841df4923358d24721e29a4395fd8410f672286fb862f234d7afe446 + fbca241edc3784af; + 7dbce9ba43a39089de20de70d0544b5151db0a16e9769e8f2fc12c7f839fab269a0056284a697ffd4113a1cf43b5d5bdce2d86dead83f5a356e9106bedf908db61f1119f9700260ea9379cc723 + 2184d217158f + "" + "" + "" + a8dca51e818d1620; + ee8ca42e75614739e9007f234fbcd86b0ad8f641a0449b6d9b0f99d1cb4a57a4d6f987feb0ade90aa1d81c4f497b3734be301da3e25fe692629db57311f422f3a1573f9e0553a23e96265e4326 + fa532d713686 + 3e + "" + "" + 22724c59a99e8a28; + 5b4bc6c99ade3d4eb23cacdf6e42ad8ca13187eba1532920ba31582b3793b05fa65e9f80c5814b91f4d3c581c7b16c46b484859c6d19eebaf124681aa3be9943307fa4ef095ef8e7e50b703dc0 + 420e74227c93 + "" + 51 + cd + d31ba86abcc74ed5; + 366ef8e98e1e24b48aa989dbb8d0f10471ae5428a6012fbe4f5cb2dab2863e574842cc0b3774e00dcfa63b0db1716c7e916a26fc2e198f8db63ab59955989497782f16c5816270ef3fbe4ea22f + 484ddc + "" + 12ec8f4bdbd6ebdfbafb21fcf5427dbee5f95b53a0b4cb6d + 377776c7a23f367f4b797164000341b828e9af1528512d7e + 640622b80de68169; + 7c128b79f4657895f4b0ba518dd61436140f20d40224baac3a602da83cb254a7e03f052c63c1f3f00f301cc944a1789133bb8048f07dc123f2ca7e20c83988e4bfea6d561ab5aea542db544a14 + 376d5d52f7 + 265c7a8d2fc4feef99b9dba89eb472f71d8eb5affe900d77 + 6e4cf74e52b6c86db981143082735c6473a86a5da3d2e8cb + 96695b552838f18f1d0cdede1c6e8b7a94686a80d3faafb2 + 1b2ffe9cea3bdd6f; + b8602ebbaf08bf9315fba15f46714bfd2c8312fb5744dfe84615ddb93f15360161f2efb1fc39b8b6ad97427dcaa0435bee7f3a5c11fd01b9c120aa6004f84bcba838a1c33beb4087719135b355 + dce9ffd6fd63 + "" + 9f192e4c2c9a2752bf74a3f63408d3b27df51f44ed5537bfb0162f05ed + 15dacd515d731592ab85c1b5d9f3dbcde30179b31c493a15f6af916588 + 99a03f7a639d9ac1; + bad1b2c36ceec1dc407475b8e05fcb5ee66c7205f21804c3b73451dc9a3aed7667c6342c8355ff66b91eeffa115cf118eef301f2c93fda303878f7987116dba62d93a7da70274ffe5a6506e4e1 + 439de76cc9d3 + 32ab03510df3c7d35dc526b5b7785400f53d34 + b5d55fcac5fbeadd81456bbe6bcedb015be40bfbda656483b32fc4d0a9 + 82df9af04d4792ef8a746a950613ca561e9d1e395b28cd4efb20400d03 + b866935e219f4573; +} + +rc5-ocb3-mct { + 56 5d65dacd57c2aa33; + 52 03beeb48bcdb2c18; + 48 01d2c1abfdcd3689; + 44 4fe9063599fc965e; + 40 02c7d56243840c7c; + 36 b8835ac12d93de0c; + 32 c04dd9d0ccbc4df6; + 28 7d59856e20a6e739; + 24 8a1db814d18c6c97; + 20 99060d584b19a39f; + 16 722f822efb96b14b; + 12 20c08832fef3cccd; + 10 3bb20b4bb9ae613f; + 8 85f66ee439d96c46; + 56 f81750a75668; + 52 67fff337eefc; + 48 53149ad225e2; + 44 6cf6c8f56720; + 40 795b55a03080; + 36 a2aeb71e7493; + 32 4581768fa39c; + 28 e03e2ac2d905; + 24 f0c24fe14ad1; + 20 ba83f3fe63f0; + 16 c42c1512c9fe; + 12 d1934f3572cd; + 10 badab855071f; + 8 084797262a89; + 56 0c1bc6bd; + 52 805a3d32; + 48 9252506e; + 44 f848c865; + 40 f4a16d1d; + 36 57b79a09; + 32 e8b16e4b; + 28 a6a0961d; + 24 04dd92bc; + 20 8ca6413a; + 16 2b7d2d10; + 12 87440aab; + 10 3277a842; + 8 b84a6c79; +} diff --git a/symm/t/rijndael.local b/symm/t/rijndael.local new file mode 100644 index 00000000..e9517f14 --- /dev/null +++ b/symm/t/rijndael.local @@ -0,0 +1,1946 @@ +### Local tests for Rijndael. + +rijndael-cmac { + ## NIST examples. + + 2b7e151628aed2a6abf7158809cf4f3c + "" + bb1d6929e95937287fa37d129b756746; + 2b7e151628aed2a6abf7158809cf4f3c + 6bc1bee22e409f96e93d7e117393172a + 070a16b46b4d4144f79bdd9dd04a287c; + 2b7e151628aed2a6abf7158809cf4f3c + 6bc1bee22e409f96e93d7e117393172aae2d8a57 + 7d85449ea6ea19c823a7bf78837dfade; + 2b7e151628aed2a6abf7158809cf4f3c + 6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710 + 51f0bebf7e3b9d92fc49741779363cfe; + + 8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b + "" + d17ddf46adaacde531cac483de7a9367; + 8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b + 6bc1bee22e409f96e93d7e117393172a + 9e99a7bf31e710900662f65e617c5184; + 8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b + 6bc1bee22e409f96e93d7e117393172aae2d8a57 + 3d75c194ed96070444a9fa7ec740ecf8; + 8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b + 6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710 + a1d5df0eed790f794d77589659f39a11; + + 603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4 + "" + 028962f61b7bf89efc6b551f4667d983; + 603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4 + 6bc1bee22e409f96e93d7e117393172a + 28a7023f452e8f82bd4bf28d8c37c35c; + 603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4 + 6bc1bee22e409f96e93d7e117393172aae2d8a57 + 156727dc0878944a023c1fe03bad6d93; + 603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4 + 6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710 + e1992190549f6ed5696a2c056c315410; + + ## Locally generated tests. + 60d7bcda163547d348b7551195e77022 + "" + 63f719651118fd4d45cb4feebc3150cb; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + bc9d9dfba6e312cfe8e6c500a1d805d3; + 8f86edd1dc9268eeee533285a6ed810c + 9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77 + ba66e97ee7b233119abc32fa42be9401; + bf79192a5b50ade5d9cd739a3d1f337f + 29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21 + a51011f5c5d190016cf3e9db6fb32fbc; + 635c6d62c9269029df3e6057acc87638f5080467 + "" + 9285e3dc234cbd47605641edd2052999; + 33d9ff61cdbda3b3e9878731ebfedd4705e505da + 14 + edc6f130780024d1b8b18361790d949c; + 35dceaa7b1cc49ae1d50c38201a894476b3f102b + 752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3 + ac7f798e3227ecb5e4d868c6f07ce3d0; + a4f3ebbbb18ac6c95a97a48030370c33d090c542 + 15abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829 + 9045fe42a3307e0d86fa17dbaa73196b; + b94586306fed54154f8f28523c03d4de1600157846b710ee72807a22 + "" + b74dbdd96ca8714c2223ce172d7c5541; + 19bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d + 42 + bcbf74240e12721322ac24676c8eeb16; + f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e + 533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5c + 1889506d1415435dbc580f7b05c1c2e4; + fb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc81517 + 84873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6 + ccf79bcc9696a3887f23f791aa3fbafa; + eabdff3bcd211499268878db + "" + 72c93457d9e50f9ce47227ce159722c7; + f30f1dad89d4b9b12012e471 + 3d + 63c431d9cc49118b4af79b5dbf2efded; + f46795630e7952d22bb02d71 + 00b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da0 + 86b6a12fb898bf6a4cad2052a70864ad; + 8da3aefc5f8584b7c5e61766 + 9c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb6 + 3a2d6cd3d65ba29059613d7e6b6e1278; +} + +rijndael-ccm { + ## From the Housley, Whiting, and Ferguson submission to NIST, somewhat + ## rearranged because of the bizarre (and undocumented) nonce structure. + + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 00000003020100a0a1a2a3a4a5 + 0001020304050607 + 08090a0b0c0d0e0f101112131415161718191a1b1c1d1e + 588c979a61c663d2f066d0c2c0f989806d5f6b61dac384 + 17e8d12cfdf926e0; + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 00000004030201a0a1a2a3a4a5 + 0001020304050607 + 08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 72c91a36e135f8cf291ca894085c87e3cc15c439c9e43a3b + a091d56e10400916; + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 00000005040302a0a1a2a3a4a5 + 0001020304050607 + 08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 + 51b1e5f44a197d1da46b0f8e2d282ae871e838bb64da859657 + 4adaa76fbd9fb0c5; + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 00000006050403a0a1a2a3a4a5 + 000102030405060708090a0b + 0c0d0e0f101112131415161718191a1b1c1d1e + a28c6865939a9a79faaa5c4c2a9d4a91cdac8c + 96c861b9c9e61ef1; + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 00000007060504a0a1a2a3a4a5 + 000102030405060708090a0b + 0c0d0e0f101112131415161718191a1b1c1d1e1f + dcf1fb7b5d9e23fb9d4e131253658ad86ebdca3e + 51e83f077d9c2d93; + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 00000008070605a0a1a2a3a4a5 + 000102030405060708090a0b + 0c0d0e0f101112131415161718191a1b1c1d1e1f20 + 6fc1b011f006568b5171a42d953d469b2570a4bd87 + 405a0443ac91cb94; + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 00000009080706a0a1a2a3a4a5 + 0001020304050607 + 08090a0b0c0d0e0f101112131415161718191a1b1c1d1e + 0135d1b2c95f41d5d1d4fec185d166b8094e999dfed96c + 048c56602c97acbb7490; + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 0000000a090807a0a1a2a3a4a5 + 0001020304050607 + 08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 7b75399ac0831dd2f0bbd75879a2fd8f6cae6b6cd9b7db24 + c17b4433f434963f34b4; + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 0000000b0a0908a0a1a2a3a4a5 + 0001020304050607 + 08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 + 82531a60cc24945a4b8279181ab5c84df21ce7f9b73f42e197 + ea9c07e56b5eb17e5f4e; + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 0000000c0b0a09a0a1a2a3a4a5 + 000102030405060708090a0b + 0c0d0e0f101112131415161718191a1b1c1d1e + 07342594157785152b074098330abb141b947b + 566aa9406b4d999988dd; + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 0000000d0c0b0aa0a1a2a3a4a5 + 000102030405060708090a0b + 0c0d0e0f101112131415161718191a1b1c1d1e1f + 676bb20380b0e301e8ab79590a396da78b834934 + f53aa2e9107a8b6c022c; + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf + 0000000e0d0c0ba0a1a2a3a4a5 + 000102030405060708090a0b + 0c0d0e0f101112131415161718191a1b1c1d1e1f20 + c0ffa0d6f05bdb67f24d43a4338d2aa4bed7b20e43 + cd1aa31662e7ad65d6db; + aca23752615c82c1d454c4fc1462dcf3 + 00b9965d963ec163c54530549a + 20f2c84a078983d6 + d9215a08e37911f08e13e868d561fd8de3bc968e0978ae + 8ca7df83589d89f1e2f9633a4e219e4e8c4daf918cbd4a + 795fa85da6e5711c; + aca23752615c82c1d454c4fc1462dcf3 + 0044144a825d7363c54530549a + 23bc9db76f5e4761 + 5297b4a9984845b03b01cf4794fa66cf27cc89c002ff4a4b + c7d563f1e02eb4f54919ae707d6cc9573ca85434f3559b30 + 78aeda0f601d877e; + aca23752615c82c1d454c4fc1462dcf3 + 00aaf7bf9d75c663c54530549a + 86eec4ba8409465f + 875547667e2424abb2a30fde33b6e81c2b5c1c5629b262555c + a15c03b3d37d1f5fba858d394997e935c44985212cfaed5037 + bd7dd7a68f95a476; + aca23752615c82c1d454c4fc1462dcf3 + 0040da4cf416fc63c54530549a + 15801a12adb41e13223d9c4f + f1d25ee5bd3014d5eb7254c3c62ded9d1dbb7d + 0c9c100d74193c6d5679cd01b6418fff3a4fe4 + 7cf0866237842658; + aca23752615c82c1d454c4fc1462dcf3 + 002c2cbdfa28bf63c54530549a + d9808ff2b59b6a89bf9c4a82 + 05bba8822b40f4803253fb91f0b5bcf60ee5dd95 + b5b3b7fab03d662e1842333328466dd81dd8fe3d + 6f8c861ab1617dc3; + aca23752615c82c1d454c4fc1462dcf3 + 0016230909f7cc63c54530549a + 9b85df31226b387fdf8ddd4d + 4eb993044b71beddc6ef3f287197e4d46e9f29e427 + a0e19481ba549ce66fadd81937a09a4f542b2f421d + 12695462fd931591; + aca23752615c82c1d454c4fc1462dcf3 + 00797b71e3c96963c54530549a + e7e6473a07dacca4 + 9436254b379e38d73861ca027fc79b0440aba519e9e1dc + 0d22d68dc1d39934f8e5882c2058436a0cc58e03258b4e + 2bb39e01a568aba1f1ba; + aca23752615c82c1d454c4fc1462dcf3 + 0083ae22deb9b163c54530549a + a1c6b900678806b8 + 37709803b3fff94ffac1150b28a3cef1bf4feea0ff19541c + 3103c511e43dc5e01aba07db0b84a443a1e3425983c3fe7e + 19c626fd947eafb9c1b3; + aca23752615c82c1d454c4fc1462dcf3 + 006541e08f013463c54530549a + ea6abbb54793ecc2 + eb0e990f88cfb0e78c1d6196890f8b6fa7787fe2dd85a72355 + a449f8b7a3c9d0c3fca9a6e7a89953fdbbb5d4d05dc77f67ae + 4efbc470d8a0b1c4f967; + aca23752615c82c1d454c4fc1462dcf3 + 00ede32aa3875a63c54530549a + 869cbaf565fbb429d4603ace + 6cd5e33d9e5ff526e21b24f40d6b15e5ed25fb + 450c728aac9be3105cbe74653ffd52feb4a5ad + d6db7bc4dfdfc165dd93; + aca23752615c82c1d454c4fc1462dcf3 + 0073331529b3db63c54530549a + 934cae407d3e300ae7111b43 + e9a5e8b187d1e7baa3ad94fcf9e1b25aff726259 + 5f7716b16a6218b2a44033c29260df1d75caadd4 + 583c50b41845b3867f21; + aca23752615c82c1d454c4fc1462dcf3 + 00cdf8f729be7363c54530549a + 6dbf3223e9758ce37ed8e2a9 + ab8db40bc61588976d79d96e3012f0ff60e37e0732 + 220bb8f4aba55c7d573f1f2fbd3d78a4361c665f51 + 659f6d2e866db4de0e97; + + ## From NIST SP800-38C. + 404142434445464748494a4b4c4d4e4f + 10111213141516 + 0001020304050607 + 20212223 + 7162015b + 4dac255d; + 404142434445464748494a4b4c4d4e4f + 1011121314151617 + 000102030405060708090a0b0c0d0e0f + 202122232425262728292a2b2c2d2e2f + d2a1f0e051ea5f62081a7792073d593d + 1fc64fbfaccd; + 404142434445464748494a4b4c4d4e4f + 101112131415161718191a1b + 000102030405060708090a0b0c0d0e0f10111213 + 202122232425262728292a2b2c2d2e2f3031323334353637 + e3b201a9f5b71a7a9b1ceaeccd97e70b6176aad9a4428aa5 + 484392fbc1b09951; + + ## Other NIST examples. + 404142434445464748494a4b4c4d4e4f + 10111213141516 + "" + 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f + 7162015bc051951e5918aeaf3c11f3d4ac363f8d5b6af3d369603b04f24cae29964e2f2bf9d31143f72527ce2db402eab7660e4a10b08e82266517cdf60267f9 + c66b655c; + 404142434445464748494A4B4C4D4E4F + 10111213141516 + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f + "" + "" + e84023f8; + 404142434445464748494a4b4c4d4e4f5051525354555657 + 10111213141516 + 0001020304050607 + 20212223 + 18ee1730 + c8c326d5; + 404142434445464748494a4b4c4d4e4f5051525354555657 + 1011121314151617 + 000102030405060708090a0b0c0d0e0f + 202122232425262728292a2b2c2d2e2f + 2232b6e0924148ae7239bcbd1a0f7ecb + 56e9cc28aa67; + 404142434445464748494a4b4c4d4e4f5051525354555657 + 101112131415161718191a1b + 000102030405060708090a0b0c0d0e0f10111213 + 202122232425262728292a2b2c2d2e2f3031323334353637 + 8081316fd89624d62ce7637fb94995b6631c50d61586de01 + 42366952505f995a; + 404142434445464748494a4b4c4d4e4f5051525354555657 + 10111213141516 + "" + 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f + 18ee1730f4490ea847a8e9c532c69f9c0a539a585c1e7b6a5af919f4819088a96ed632555098d3007e7d963c7bd013eb307671d0fbc39a0df4a26a9f4b9e4dad + c9ce2fbc; + 404142434445464748494a4b4c4d4e4f5051525354555657 + 10111213141516 + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f + "" + "" + f1fb2a57; + 404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f + 10111213141516 + 0001020304050607 + 20212223 + 8ab1a874 + 95fc0820; + + 404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f + 1011121314151617 + 000102030405060708090a0b0c0d0e0f + 202122232425262728292a2b2c2d2e2f + af1785fc0f5ea7d0cfba837246484497 + 94b826c8849e; + + 404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f + 101112131415161718191a1b + 000102030405060708090a0b0c0d0e0f10111213 + 202122232425262728292a2b2c2d2e2f3031323334353637 + 04f883aeb3bd0730eaf50bb6de4fa2212034e4e41b0e75e5 + 2b48c8766f7e7649; + + 404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f + 10111213141516 + "" + 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f + 8ab1a874f6853f2443a59500f78d17272d6d39dfa6d0e65107b10700c2ce9ee8663d3e2a01c2e12c32e9377442231920be53278f4f60a972b709bb16932936ba + 3fbd0fae; + + 404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f + 10111213141516 + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f + "" + "" + a6cf8230; + + ## Locally generated tests. + 60d7bcda163547d348b7551195e77022 + 907dd1dff7dac5c9941d26 + "" + "" + "" + cf28ba78; + d0c6eb14ad568f86edd1dc9268eeee53 + 3285a6ed810c9b689daaa9 + 06 + "" + "" + f258e4d7; + 0d2d4b6003062365b0a54364c76c160f + 11896c4794846ecfa14a71 + "" + 30 + d6 + 0c31647b; + c9f137120634c9519848a877ff77bf79 + 192a5b50ade5d9cd73 + 9a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21 + 635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49 + 41b97c9616d0af69288f13e20d74901645bc9b5263044121e5562fa5b0e5ef40a2639909c2e07e329cc50737613a2c53 + e992acc597653980b46bc43fd471eb5f; + ae1d50c38201a894476b3f102b752eb9 + 529533966f27043eb6 + 21b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6 + c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3 + 8c314091d48b18dba473f0180ebfa878c920562f0d3c63303cafd8b92e31c35ca8e30e5dde711d30e7360b70030864de8d8156be5e + 672d9df3a0e99ed948e4f598a913b421; + 349829b94586306fed54154f8f28523c03d4de16 + 00157846b710ee72807a22 + "" + "" + "" + 9205b2da; + 19bfb474fd71d891f24bb65d1563259f9eb53b57 + 1ea629c54d57dd2d42f708 + 00 + "" + "" + 9ae9b8a9; + df9fcbaca48b77dba189196d1ebba10b0467cb9f + c2712a199e533fa9156308 + "" + cd + 19 + fab4799d; + ec3f768281e040a9b9a222bd689aef66f5306ceb + 0c6b08ac8b0a22260c + 571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da + 6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf3 + a11307a1d9df486ff782f6643324950ec651e2df47bab6ef1254fa7d04b59bca5f509bc9e781ed797105d39fb509de45 + 27d12d4fb2bc29dc306d5c2240e4894c; + 0f1dad89d4b9b12012e4713df46795630e7952d2 + 2bb02d7100b8b64937 + 7d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da0 + 8da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7ca + 45adc79632d8fdc8470e9ea47e2523d2a9ad568b2817b5295c078756df3d7f584aaf4b4e9667023b719c1ef7ad9cb72bdf31746f56 + f1855db5745f0561fd8113b2ff6006ce; + dcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498 + ad0abef8bc4fcb70e27e98 + "" + "" + "" + a84a331d; + ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4 + ae985511265febd11c1647 + 20 + "" + "" + e4256cb2; + eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0c + fa9138ddc39908445608fe + "" + 95 + 52 + 87c71b52; + e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3 + f9099c5ffb824173d7 + 634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc + 9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911 + b000328931c8a1484cae26f4f7be0415d58858fcff326136d37fd981492c5851163f68326cac9d4b80f29f5c157a28c2 + 9b9c5705e2d569fc1b280731e4286027; + e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c9 + 67c0a458cb948bdd40 + 9b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8de + b9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb4 + d038ac6646cb2b6da23963eac488def0a233d63e097f9b981d322f96d6cad2d2c2be978d566a5afd8b20ecff4f1c8765ee5446c2a3 + 28b572f708c9a6eb036444c0a9e8818c; + 4d65bad397abfaf529ee41cf + 9a05c7efedef3401539c51 + "" + "" + "" + 66c301e7; + d2a90bbf7f1bfc338ab0ef57 + 46ea8fdcccd213e33f7e8a + 57 + "" + "" + df5a4e4e; + 18fd25014107c8e7d715a92a + dd9589d1f5c054b2d98351 + "" + 46 + 2a + 0c3bbfb2; + 05ec590294a319b9802068a9 + f891bc5ba5afabf8c3 + 122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde9 + 5759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4 + 5c4a984366df29ee88817bba556a52b0c17ce5c3a337caac667c792cd1d7b705e3db87734963b51d606d8022346fc267 + 1494a9ba0a649a71409b719d821d546f; + 563d405e51881e99027b8ab9 + aea3ccf860b0009740 + 763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3 + aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd6777 + 73f618f0bfb917a6ca4f6b7872dbd148fa97bbf8ab044f3331410eef1be00037e9293d851e99ee70c65cad306c4fc0cee754ee1e5c + f1c35f66bbb6b69b6c7aa3e7ed23e47e; +} + +rijndael-eax { + ## From Mihir Bellare, Phillip Rogaway, David Wagner, `The EAX Mode of + ## Operation (A Two-Pass Authenticated-Encryption Scheme Optimized for + ## Simplicity and Efficiency)'. + + 233952dee4d5ed5f9b9c6d6ff80ff478 + 62ec67f9c3a4a407fcb2a8c49031a8b3 + 6bfb914fd07eae6b + "" + "" + e037830e8389f27b025a2d6527e79d01; + 91945d3f4dcbee0bf45ef52255f095a4 + becaf043b0a23d843194ba972c66debd + fa3bfd4806eb53fa + f7fb + 19dd + 5c4c9331049d0bdab0277408f67967e5; + 01f74ad64077f2e704c0f60ada3dd523 + 70c3db4f0d26368400a10ed05d2bff5e + 234a3463c1264ac6 + 1a47cb4933 + d851d5bae0 + 3a59f238a23e39199dc9266626c40f80; + d07cf6cbb7f313bdde66b727afd3c5e8 + 8408dfff3c1a2b1292dc199e46b7d617 + 33cce2eabff5a79d + 481c9e39b1 + 632a9d131a + d4c168a4225d8e1ff755939974a7bede; + 35b6d0580005bbc12b0587124557d2c2 + fdb6b06676eedc5c61d74276e1f8e816 + aeb96eaebe2970e9 + 40d0c07da5e4 + 071dfe16c675 + cb0677e536f73afe6a14b74ee49844dd; + bd8e6e11475e60b268784c38c62feb22 + 6eac5c93072d8e8513f750935e46da1b + d4482d1ca78dce0f + 4de3b35c3fc039245bd1fb7d + 835bb4f15d743e350e728414 + abb8644fd6ccb86947c5e10590210a4f; + 7c77d6e813bed5ac98baa417477a2e7d + 1a8c98dcd73d38393b2bf1569deefc19 + 65d2017990d62528 + 8b0a79306c9ce7ed99dae4f87f8dd61636 + 02083e3979da014812f59f11d52630da30 + 137327d10649b0aa6e1c181db617d7f2; + 5fff20cafab119ca2fc73549e20f5b0d + dde59b97d722156d4d9aff2bc7559826 + 54b9f04e6a09189a + 1bda122bce8a8dbaf1877d962b8592dd2d56 + 2ec47b2c4954a489afc7ba4897edcdae8cc3 + 3b60450599bd02c96382902aef7f832a; + a4a4782bcffd3ec5e7ef6d8c34a56123 + b781fcf2f75fa5a8de97a9ca48e522ec + 899a175897561d7e + 6cf36720872b8513f6eab1a8a44438d5ef11 + 0de18fd0fdd91e7af19f1d8ee8733938b1e8 + e7f6d2231618102fdb7fe55ff1991700; + 8395fcf1e95bebd697bd010bc766aac3 + 22e7add93cfc6393c57ec0b3c17d6b44 + 126735fcc320d25a + ca40d7446e545ffaed3bd12a740a659ffbbb3ceab7 + cb8920f87a6c75cff39627b56e3ed197c552d295a7 + cfc46afc253b4652b1af3795b124ab6e; + + ## Some local tests for additional edge cases, generated using the toy + ## implementation in Python. + 60d7bcda163547d348b7551195e77022 + "" + "" + "" + "" + fc65784451ea97468ec025e17a709456; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + "" + "" + "" + d8da3364e510165ed5afd2aab762f5d2; + 8f86edd1dc9268eeee533285a6ed810c + "" + 9b + "" + "" + 715b06133d886f3b8fb8fdfcadd0fa5c; + 689daaa9060d2d4b6003062365b0a543 + "" + "" + 64 + 69 + 16c192d8633a39465ce18da2ce132233; + c76c160f11896c4794846ecfa14a7130 + c9f137120634c9519848a877ff77bf79 + 192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8 + cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505 + 963801ede08bd2b86a3c33cf18c27d98c7c22f14c08621651e6094e72bcbd4bbf38f5e20814d465daa9c5929b9f59375 + 180ad55fa758703dd6a4e345956705e5; + da1435dceaa7b1cc49ae1d50c38201a8 + 94476b3f102b752eb9529533966f27 + 043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac + 448792431ef5eb64efcfb2e6a9bb454d7ef09598ca4bc057d9cba969328ad75c05b7da7012e5ff1826dc3c981072fc9dce719cfffa + aeaa46b633b5c3ba7db2e404af2eb9a8; + 26afa3349829b94586306fed54154f8f28523c03 + "" + "" + "" + "" + d0a749a3ae472501971c7521066a5c14; + d4de1600157846b710ee72807a2219bfb474fd71 + d8 + "" + "" + "" + 5998cfaef8d97abd4c8017aba424a845; + 91f24bb65d1563259f9eb53b571ea629c54d57dd + "" + 2d + "" + "" + 7ecfd7cde12120a79d65622bd02993f8; + 42f70800df9fcbaca48b77dba189196d1ebba10b + "" + "" + 04 + 46 + b4b2f22374e5416565ea5da09bd65726; + 67cb9fc2712a199e533fa9156308cdec3f768281 + e040a9b9a222bd689aef66f5306ceb0c + 6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc81517 + 84873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd + 78ebdb6a281df84204a58c3071a81ee62c604c4ff408d02ec9401bd284beba033e438279a8cf450bccc58ddb0480b0b1 + 8f3edaf96c1c577c99d506fa9bdd342c; + 211499268878dbf30f1dad89d4b9b12012e4713d + f46795630e7952d22bb02d7100b8b6 + 49377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d079839180 + 5da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0 + b81e04dfef276af4992a4daacad70a724bd2bc5f857d739b82781dab188f6c172f1dc3390ab9226f6a286bf89e3fd198ee3e781db4 + 1096e8cbf9132840e22c4e9618a981c2; + b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a87 + "" + "" + "" + "" + 8517441bde0b33302a5d73d756bbaea3; + 4498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc1 + 88 + "" + "" + "" + 2703e5e0acbf6d762e635e66e599c7e7; + d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c + "" + 8d + "" + "" + 21ba7e9152f7a188a570a435a9118dd7; + d0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc3 + "" + "" + 99 + 8f + 19edae1a9f72c3ec1a95456a7602fbea; + 08445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b8 + 07e6daa089c3f9099c5ffb824173d763 + 4c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9b + c597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e3 + 7da2cbb1dbb96d57e6eae7f7463cdaf220f06e96bcce1303ef6c987de22fa64d62c89f8bef1676b6c9447b03575fce9a + 83e41c3c033397193406be50be532022; + 2d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967 + c0a458cb948bdd409b687fa3a6827b + 480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c + 091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfa + 5c26f8ce44729fef7b23d7a08a6f770499d3efd779ec6975b549f418abdffc8a1fe5c279e41e3815b8667e96a4ad39aeef24bee42f + cd68c88ece3bead81778b31e8dbe34db; + f529ee41cf9a05c7efedef34 + "" + "" + "" + "" + 9fa09ea950f21cf235e494490111462f; + 01539c51d2a90bbf7f1bfc33 + 8a + "" + "" + "" + b694f1a079840c1a5306fa86a0d4bba3; + b0ef5746ea8fdcccd213e33f + "" + 7e + "" + "" + 91c2e974c399c84bdff77b962441e1f3; + 8a5718fd25014107c8e7d715 + "" + "" + a9 + 14 + 279ad0e41ab70a6751f9fbd01030784e; + 2add9589d1f5c054b2d98351 + 4605ec590294a319b9802068a9f891bc + 5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725c + b2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d9803 + cb3a052da8d3fc8c6e40de726ef40596a871d596df7b7c33b11467ba4ab39210df119a6e202267b44f86db3b4074c886 + 4ea05695bbf7f261c4e76415e3642945; + 98bd94e66eb4563d405e5188 + 1e99027b8ab9aea3ccf860b0009740 + 763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3 + aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd6777 + 03f7e555335edc0f776c210da68ddceda30e7b6d11f62aab60a17f443e6000c31ca8927b28791f8b5dcff245c82b63ebca8cdbeb9a + a860ca21635e5d2c1fa19d96a4c394fa; +} + +rijndael-gcm { + + ## NIST examples. + feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + "" + "" + "" + 3247184b3c4f69a44dbcd22887bbb418; + feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + "" + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255 + 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985 + 4d5c2af327cd64a62cf35abd2ba6fab4; + feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + 3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf43b1cd7f598ece23881b00e3ed0306887b0c785e27e8ad3f8223207104725dd4 + "" + "" + 5f91d77123ef5eb9997913849b8dc1e9; + feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + 3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf43b1cd7f598ece23881b00e3ed0306887b0c785e27e8ad3f8223207104725dd4 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255 + 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985 + 64c0232904af398a5b67c10b53a5024d; + feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + 3ad77bb40d7a3660a89ecaf32466ef97f5d3d585 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091 + f07c2528eea2fca1211f905e1b6a881b; + + feffe9928665731c6d6a8f9467308308feffe9928665731c + cafebabefacedbaddecaf888 + "" + "" + "" + c835aa88aebbc94f5a02e179fdcfc3e4; + feffe9928665731c6d6a8f9467308308feffe9928665731c + cafebabefacedbaddecaf888 + "" + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255 + 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256 + 9924a7c8587336bfb118024db8674a14; + feffe9928665731c6d6a8f9467308308feffe9928665731c + cafebabefacedbaddecaf888 + 3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf43b1cd7f598ece23881b00e3ed0306887b0c785e27e8ad3f8223207104725dd4 + "" + "" + 02cc773bc919f4e1c5e9c54313bface0; + feffe9928665731c6d6a8f9467308308feffe9928665731c + cafebabefacedbaddecaf888 + 3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf43b1cd7f598ece23881b00e3ed0306887b0c785e27e8ad3f8223207104725dd4 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255 + 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256 + 3b9153b4e7318a5f3bbeac108f8a8edb; + feffe9928665731c6d6a8f9467308308feffe9928665731c + cafebabefacedbaddecaf888 + 3ad77bb40d7a3660a89ecaf32466ef97f5d3d585 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710 + 93ea28c659e269902a80acd208e7fc80; + + feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + "" + "" + "" + fd2caa16a5832e76aa132c1453eeda7e; + feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + "" + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255 + 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad + b094dac5d93471bdec1a502270e3cc6c; + feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + 3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf43b1cd7f598ece23881b00e3ed0306887b0c785e27e8ad3f8223207104725dd4 + "" + "" + de34b6dcd4cee2fdbec3cea01af1ee44; + feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + 3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf43b1cd7f598ece23881b00e3ed0306887b0c785e27e8ad3f8223207104725dd4 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255 + 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad + c06d76f31930fef37acae23ed465ae62; + feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + 3ad77bb40d7a3660a89ecaf32466ef97f5d3d585 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662 + e097195f4532da895fb917a5a55c6aa0; + + ## IEEE tests for P802.1. + ad7a2bd03eac835a6f620fdcb506b345 + 12153524c0895e81b2c28465 + d609b1f056637a0d46df998d88e5222ab2c2846512153524c0895e8108000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233340001 + "" + "" + f09478a9b09007d06f46e9b6a1da25dd; + ad7a2bd03eac835a6f620fdcb506b345 + 12153524c0895e81b2c28465 + d609b1f056637a0d46df998d88e52e00b2c2846512153524c0895e81 + 08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a0002 + 701afa1cc039c0d765128a665dab69243899bf7318ccdc81c9931da17fbe8edd7d17cb8b4c26fc81e3284f2b7fba713d + 4f8d55e7d3f06fd5a13c0c29b9d5b880; + 071b113b0ca743fecccf3d051f737382 + f0761e8dcd3d000176d457ed + e20106d7cd0df0761e8dcd3d88e5400076d457ed08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a0003 + "" + "" + 0c017bc73b227dfcc9bafa1c41acc353; + 071b113b0ca743fecccf3d051f737382 + f0761e8dcd3d000176d457ed + e20106d7cd0df0761e8dcd3d88e54c2a76d457ed + 08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233340004 + 13b4c72b389dc5018e72a171dd85a5d3752274d3a019fbcaed09a425cd9b2e1c9b72eee7c9de7d52b3f3 + d6a5284f4a6d3fe22a5d6c2b960494c3; + 013fe00b5f11be7f866d0cbbc55a7a90 + 7cfde9f9e33724c68932d612 + 84c5d513d2aaf6e5bbd2727788e523008932d6127cfde9f9e33724c608000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f0005 + "" + "" + 217867e50c2dad74c28c3b50abdf695a; + 013fe00b5f11be7f866d0cbbc55a7a90 + 7cfde9f9e33724c68932d612 + 84c5d513d2aaf6e5bbd2727788e52f008932d6127cfde9f9e33724c6 + 08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b0006 + 3a4de6fa32191014dbb303d92ee3a9e8a1b599c14d22fb080096e13811816a3c9c9bcf7c1b9b96da809204e29d0e2a7642 + bfd310a4837c816ccfa5ac23ab003988; + 88ee087fd95da9fbf6725aa9d757b0cd + 7ae8e2ca4ec500012e58495c + 68f2e77696ce7ae8e2ca4ec588e541002e58495c08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d0007 + "" + "" + 07922b8ebcf10bb2297588ca4c614523; + 88ee087fd95da9fbf6725aa9d757b0cd + 7ae8e2ca4ec500012e58495c + 68f2e77696ce7ae8e2ca4ec588e54d002e58495c + 08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748490008 + c31f53d99e5687f7365119b832d2aae70741d593f1f9e2ab3455779b078eb8feacdfec1f8e3e5277f8180b43361f6512adb16d2e38548a2c719dba7228d840 + 88f8757adb8aa788d8f65ad668be70e7; + + e3c08a8f06c6e3ad95a70557b23f75483ce33021a9c72b7025666204c69c0b72 + 12153524c0895e81b2c28465 + d609b1f056637a0d46df998d88e5222ab2c2846512153524c0895e8108000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233340001 + "" + "" + 2f0bc5af409e06d609ea8b7d0fa5ea50; + e3c08a8f06c6e3ad95a70557b23f75483ce33021a9c72b7025666204c69c0b72 + 12153524c0895e81b2c28465 + d609b1f056637a0d46df998d88e52e00b2c2846512153524c0895e81 + 08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a0002 + e2006eb42f5277022d9b19925bc419d7a592666c925fe2ef718eb4e308efeaa7c5273b394118860a5be2a97f56ab7836 + 5ca597cdbb3edb8d1a1151ea0af7b436; + 691d3ee909d7f54167fd1ca0b5d769081f2bde1aee655fdbab80bd5295ae6be7 + f0761e8dcd3d000176d457ed + e20106d7cd0df0761e8dcd3d88e5400076d457ed08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a0003 + "" + "" + 35217c774bbc31b63166bcf9d4abed07; + 691d3ee909d7f54167fd1ca0b5d769081f2bde1aee655fdbab80bd5295ae6be7 + f0761e8dcd3d000176d457ed + e20106d7cd0df0761e8dcd3d88e54c2a76d457ed + 08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233340004 + c1623f55730c93533097addad25664966125352b43adacbd61c5ef3ac90b5bee929ce4630ea79f6ce519 + 12af39c2d1fdc2051f8b7b3c9d397ef2; + 83c093b58de7ffe1c0da926ac43fb3609ac1c80fee1b624497ef942e2f79a823 + 7cfde9f9e33724c68932d612 + 84c5d513d2aaf6e5bbd2727788e523008932d6127cfde9f9e33724c608000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f0005 + "" + "" + 6ee160e8faeca4b36c86b234920ca975; + 83c093b58de7ffe1c0da926ac43fb3609ac1c80fee1b624497ef942e2f79a823 + 7cfde9f9e33724c68932d612 + 84c5d513d2aaf6e5bbd2727788e52f008932d6127cfde9f9e33724c6 + 08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b0006 + 110222ff8050cbece66a813ad09a73ed7a9a089c106b959389168ed6e8698ea902eb1277dbec2e68e473155a15a7daeed4 + a10f4e05139c23df00b3aadc71f0596a; + 4c973dbc7364621674f8b5b89e5c15511fced9216490fb1c1a2caa0ffe0407e5 + 7ae8e2ca4ec500012e58495c + 68f2e77696ce7ae8e2ca4ec588e541002e58495c08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d0007 + "" + "" + 00bda1b7e87608bcbf470f12157f4c07; + 4c973dbc7364621674f8b5b89e5c15511fced9216490fb1c1a2caa0ffe0407e5 + 7ae8e2ca4ec500012e58495c + 68f2e77696ce7ae8e2ca4ec588e54d002e58495c + 08000f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748490008 + ba8ae31bc506486d6873e4fce460e7dc57591ff00611f31c3834fe1c04ad80b66803afcf5b27e6333fa67c99da47c2f0ced68d531bd741a943cff7a6713bd0 + 2611cd7daa01d61c5c886dc1a8170107; + + ## From `The Galois/Counter Mode of Operation' by David McGrew and John + ## Viega. Some of these were duplicated in the NIST examples above, and so + ## are omitted here. + 00000000000000000000000000000000 + 000000000000000000000000 + "" + "" + "" + 58e2fccefa7e3061367f1d57a4e7455a; + 00000000000000000000000000000000 + 000000000000000000000000 + "" + 00000000000000000000000000000000 + 0388dace60b6a392f328c2b971b2fe78 + ab6e47d42cec13bdf53a67b21257bddf; + feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + feedfacedeadbeeffeedfacedeadbeefabaddad2 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091 + 5bc94fbc3221a5db94fae95ae7121a47; + feffe9928665731c6d6a8f9467308308 + cafebabefacedbad + feedfacedeadbeeffeedfacedeadbeefabaddad2 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + 61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598 + 3612d2e79e3b0785561be14aaca2fccb; + feffe9928665731c6d6a8f9467308308 + 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b + feedfacedeadbeeffeedfacedeadbeefabaddad2 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5 + 619cc5aefffe0bfa462af43c1699d050; + + 000000000000000000000000000000000000000000000000 + 000000000000000000000000 + "" + "" + "" + cd33b28ac773f74ba00ed1f312572435; + 000000000000000000000000000000000000000000000000 + 000000000000000000000000 + "" + 00000000000000000000000000000000 + 98e7247c07f0fe411c267e4384b0f600 + 2ff58d80033927ab8ef4d4587514f0fb; + feffe9928665731c6d6a8f9467308308feffe9928665731c + cafebabefacedbaddecaf888 + feedfacedeadbeeffeedfacedeadbeefabaddad2 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710 + 2519498e80f1478f37ba55bd6d27618c; + feffe9928665731c6d6a8f9467308308feffe9928665731c + cafebabefacedbad + feedfacedeadbeeffeedfacedeadbeefabaddad2 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + 0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7 + 65dcc57fcf623a24094fcca40d3533f8; + feffe9928665731c6d6a8f9467308308feffe9928665731c + 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b + feedfacedeadbeeffeedfacedeadbeefabaddad2 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b + dcf566ff291c25bbb8568fc3d376a6d9; + + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000 + "" + "" + "" + 530f8afbc74536b9a963b4f1c4cb738b; + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000 + "" + 00000000000000000000000000000000 + cea7403d4d606b6e074ec5d3baf39d18 + d0d1c8a799996bf0265b98b5d48ab919; + feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 + cafebabefacedbaddecaf888 + feedfacedeadbeeffeedfacedeadbeefabaddad2 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662 + 76fc6ece0f4e1768cddf8853bb2d551b; + feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 + cafebabefacedbad + feedfacedeadbeeffeedfacedeadbeefabaddad2 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f + 3a337dbf46a792c45e454913fe2ea8f2; + feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 + 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b + feedfacedeadbeeffeedfacedeadbeefabaddad2 + d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 + 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f + a44a8266ee1c8eb0c8b5d4cf5ae9f19a; + + ## Further home-made tests, made using the toy Python implementation. + 60d7bcda163547d348b7551195e77022 + "" + "" + "" + "" + 58b01ea630bccf61f3b34c172d152383; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + "" + "" + "" + 4728c593444566c1f955bbf6b3d38240; + 8f86edd1dc9268eeee533285a6ed810c + "" + 9b + "" + "" + d13020f394c38a8e22c46ccd91d10d77; + 689daaa9060d2d4b6003062365b0a543 + "" + "" + 64 + bc + 4daa100a72a49783462b47a93ae6bf16; + c76c160f11896c4794846ecfa14a7130 + c9f137120634c9519848a877ff77bf79 + 192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8 + cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505 + 382909981d309ca85ad62f43d0ed0d416f8040e3517772510ff95e50d9e411319e636647904a1c7ac2d857ed1996414b + 06ba36bc635adcbd1854fcef36614528; + da1435dceaa7b1cc49ae1d50c38201a8 + 94476b3f102b752eb9529533 + 966f27043eb621b7f65b000961040ef2f9b2fc + 5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93b + 7629cb94f9f709fd7c0988e50e935c3f95dc15a4f49207d62b3ba01fe62f0733842b97e72753292de7f4b3d0518ec30933d80bb3c93c5f2165 + f894c92668f0264a7f663568f38c3d71; + f4f2aad2605faee2b03fb648e27fff63 + 102758fe2b69ac26afa3349829b945 + 86306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9e + b53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e0 + 08bcec80c6486cc37d15f4da0dd221864d01b6bf9726ea9de673625a80e07e1250da4071099ffc8b50dc5cd1bfaaac50abef3d1b5a + 9456d186568dd1aca2e61c96d2ae9998; + 40a9b9a222bd689aef66f5306ceb0c6b08ac8b0a + "" + "" + "" + "" + d18fdc91e2ace4c8f4d66cf473fb42db; + 22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95 + 21 + "" + "" + "" + 93bcc629e1dc644f4f002440da2c9cca; + 4ade49cb3b6f5fe8368131115c037ba323fe1dc8 + "" + 15 + "" + "" + e87f107bb704c288cc68519cec9fa3d8; + 1784873f0eb5b647da6794c18b5337685a96ed65 + "" + "" + b9 + c1 + c59a50c109f521ba596b3bfdff74fe9d; + aca338527ef19b09c063c46f88de9fd41e72d7b9 + 7e23e6eabdff3bcd211499268878dbf3 + 0f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa92 + 1451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1 + 8068670d29a2a061b8375eb1e34259255991e9fadde3c5662930c9d29fe66fa5d513bfd6f2201e1503974444c827154b + 67f81d876969b8f8af546599fb81b929; + ecdf3d264a7f16cb16c2e815f422cdf0c8e30308 + be3c31e6bc58c0b7cadcb658 + b970e47479a684b5aefa69a4cd52147ed12ca9 + 86981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720 + 23d16173096538a850efd193113ce4664d122a0e5ef73a70b50b57304b62704f65b9b1b1167d3e9a3cc66f95b873a856a05de800a91c2d43bc + c2a7ef96a5228db104f6a11034e50f8a; + eef9eb1c8dd0b00951f284649016ed0045633185 + 4bc78bf43966eb0cfa9138ddc39908 + 445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d763 + 4c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccb + 9ef6b1732748b5f4fee62e025d4fa736336574ede8e760c680d546ecd9c51a03b3bfea4f3eff602cacdf9822717325ffff92196aa2 + 1279f19bf183b1499da8da81e174d2b8; + b2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4f + "" + "" + "" + "" + 565ff4cb468ce9c2c53451df7cc70651; + fa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6 + 77 + "" + "" + "" + e5f4f21a54e3788920c3fda8e47a561a; + 8554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a682 + "" + 7b + "" + "" + fea5e7d3d32a547d19d029133e417f4c; + 480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8 + "" + "" + 74 + 2c + a0b8a9979dfb02faac0cfd7798f31e6f; + 3d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b085 + 1e5ca605ac8451399587011677508a15 + dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338a + b0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b980 + c5c15ee7953a0b74712d9cfe36c7270a94c265f1af75b48e9147b54bf3509bea55e58c6ef3d7e60db1270d6f5f56d37b + 94d5625b8c1c2dc0eb7914e717dd640f; + 2068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff + 59a332ba58d5d5589bfe0797 + 53ee1a957eb6d6699e6b7ea2725cb2dac07ecd + e95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99 + 43f463f1b21cd0f9246af63db9eacb644edaa029de296e1e70d30a6d944e65ed2690d1a0abee3fc608b816f6b80cb15f044ea37d146f92f4c5 + 3b78d38c982a0c529ad66d6243694de8; + 027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c + 69d80ea12ff4bb5f069b8a2e86041c + 1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba600768175 + 23bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e3395 + d76bde841be1e0f1c79d55aba162df14df0d8d27a79006ae86206959988ee72bdc2f865964dfb9f9367c28ff87aefdd0ffa01d9d97 + aaa345866f4b3dbee0f6213cac96bd7b; + 8b8c2e2352fd61e4fa8fec81 + "" + "" + "" + "" + 059b6263146de5fb545a936fc848b0b4; + 6ac861a8b33779f09e7a10fc + 02 + "" + "" + "" + 58624b8c9053c43796880707b3d67f20; + a8f48afa3080ee119a52a9a8 + "" + 17 + "" + "" + 687f0761db05bcdb0388336d76fd22e7; + e4f2b94b0820cab383a8cffe + "" + "" + ea + 18 + 767802f12d42935d7b001884afc02a9c; + 7c486315799dc875fba578c8 + ec4837898a92142b5b0677da1ac27311 + 7b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c88088476892114 + 50ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d40414784 + f32ff4b45a2e730c569689c1778053d0a0d98ff6ca284a29d5dec2d196cabe0b2ff7cccd2d76677cfa6f7f3f327e95dc + 6a8c65bf4d69020ca3653fe92b8a0750; + 2941feeffdc2eb44dc8c0d5e + 8f444f7f4e0c893959b74dc2 + 3a7bb40e7e0013e5150686d2301b43a15a84e8 + 1d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726 + c4af011456e8d101166565373ad9e8f158794f83fd254b98c7c8b0fc4bf23d0c2dd3158db30946c967d9eab008d6a526e6c2bf28b0a615fd76 + 81383ad066041311a2eb1ab37d6c14eb; + d2810391b3f9d10c39b07ae8 + f08ce7cee4758a386a9943e97dedfb + e61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98 + edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bd + 502ab4639cc0336813c1e56e627ca9fd05ae8a04bb2b5a5dd7c03a5a4fc64ec1b9222fb965ee6c675f52bf3815a88d8a0ab837ad7b + 66578408dd93abb230ea3124f859308d; +} + +rijndael-ocb1 { + ## Rogaway's tests, from http://web.cs.ucdavis.edu/~rogaway/ocb/ocb-test.htm + 000102030405060708090a0b0c0d0e0f + 00000000000000000000000000000001 + "" + "" + "" + 15d37dd7c890d5d6acab927bc0dc60ee; + 000102030405060708090a0b0c0d0e0f + 00000000000000000000000000000001 + "" + 000102 + fcd37d + 02254739a5e3565ae2dcd62c659746ba; + 000102030405060708090a0b0c0d0e0f + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f + 37df8ce15b489bf31d0fc44da1faf6d6 + dfb763ebdb5f0e719c7b4161808004df; + 000102030405060708090a0b0c0d0e0f + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f10111213 + 01a075f0d815b1a4e9c881a1bcffc3eb7003eb55 + 753084144eb63b770b063c2e23cda0bb; + 000102030405060708090a0b0c0d0e0f + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 01a075f0d815b1a4e9c881a1bcffc3eb4afcbb7fedc08ca8654c6d304d1612fa + c14cbf2c1a1f1c3c137eadea1f2f2fcf; + 000102030405060708090a0b0c0d0e0f + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021 + 01a075f0d815b1a4e9c881a1bcffc3ebd4903dd0025ba4aa837c74f121b0260fa95d + cf8341bb10820ccf14bdec56b8d7d6ab; + 000102030405060708090a0b0c0d0e0f + 00000000000000000000000000000001 + "" + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + 4c9b676705ff2df05503872aa3d9e9b122c6b0ec060819146d9c887bad494417b63b4b2b3d9c3a4cd156856564c4a31be812a95d43e76ccf9811cc3a7613b0567bbcabf1a0f64f5245098c239ca7935765a7d402b01b671f1c600bc9a6823025c370a32da44a86911dce981ccaa7e3e720552bf8dd83918d8688e2347ba8691457bc25ab99a51a4388c3c7fad8a71e0c25fa185d2aa710dd9bb93cf2185ac950380732eef63549adcd451e70a0275b070fe1f9e338321aa57de832e1893f5febc0b2f0a6221d1aa187b9f152d20c259ed105c1a4be374993f4963074ef2676621109a03e628286124aefc8a3038b65103aa628f3e6bd6e1659ea0508185679d9a03b0794b914850cb4528293f7e992895a3e80337c23dbc95be1d3502cb9f8961e7dbe22898dc97b75fefaa75b4b3115969af05f54850489e007ce003d8023f490e37845f54d3c6dc3521fae9c34365091393f21139c96be6101a2bdc9dbc36902b5bd19686768154b011270157882f32dfef2a272be3cbf7e5d90ec1b6e374b4a4b806d83913e3df933e8caf5e02b1093b2a2991b34f98a41824a15b26a04a18f287024240d5347a2f3501546aac9c5b6e3f5010d9e2036c415d093892303050eaea499256eb83cba3ad4249537cbc250505024fe413965db1c41a77456711d50933249c63bd006716c4cc6ebf59c03c25a3ac3d06d7713c752f415f9ef59571885f38468c3f11bfd8111f839f080f544cb0c5ab9f87606287e314afe655510ceb8a62abcaef4e65e314f45b10e9858a175207356e9a8ac093f469ee587c18396f8965ce52e894b0bd29011b22f1e67abc16dcb948be141693fe31db635487285eeb4f8b4d5d13e511218759941850cd71fc898f8ba4cf1a4c23b3588dbf1e3e7c86efb113c8820e338a5d90d30c7d854a9ad7582d853d39cd3649cb67e3308c70bc75b732ae744aa126811034ff893829e554af51c83e1f004c3b7c9d0432978be459beaef6824b9cc5f370aa47b8d9edf583c3c84ef695705c95d59a428a675c5c788339ca737f2ec1cb6e83288b5bbfb6d1f81f47659f8f44118d76e900bdbc8094baa4bd950647abe22516a50bc85ea94410f985519076e34696b238262a00ebe889d58b09b81ee1f0b31f864a26978046ac24f1332559b6c5edc24748407e19f169c32d5d3f8ca6f71e4a5c2f72add2185857fde5749d5fd63f5b3658daa3dbaa1b0844fea3c8d2eb5e17febcfbfe44f4cf931129431ff51d6acce7e05107d6c055ad27beb185f7349ea060440a508b40186ec9732f84d21ae158969b671ac0d2ab823399220d75ec7cb50c29de3df974ae1e8c2465e3ecc207160c593443e424a57aaaee3c884632d979ccd0b6a239e1c3fdf777aa556a3c8815c2f8d1496a60048e2b971 + ab335f725475e33e90ab8c1e4891596d; + + 000102030405060708090a0b0c0d0e0f1011121314151617 + 00000000000000000000000000000001 + "" + "" + "" + b6e92be21127830a690f443f5ce8546d; + + 000102030405060708090a0b0c0d0e0f1011121314151617 + 00000000000000000000000000000001 + "" + 000102 + c21ef1 + 09474d786d4640e823f52ff63ec5359a; + + 000102030405060708090a0b0c0d0e0f1011121314151617 + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f + 3a709f22daf4c1bcf09cf1c2a0f5beff + 98d49eb3468988d06d7cb32c438f1f23; + + 000102030405060708090a0b0c0d0e0f1011121314151617 + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f10111213 + 8e951e2a2fb4ede0397cec6ba5dad5b22137f07d + 305767a31bc9e344f7f79843d1a268b1; + + 000102030405060708090a0b0c0d0e0f1011121314151617 + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 8e951e2a2fb4ede0397cec6ba5dad5b247ff19f214fd464e821c63c26e4a11e9 + 63cea28204ef06e5a21a8780ea05050d; + + 000102030405060708090a0b0c0d0e0f1011121314151617 + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021 + 8e951e2a2fb4ede0397cec6ba5dad5b235e6b8a5dcb0bd0017bfe98111352d3edf3a + dfec4b4ed2f95c305d59d79edbf62833; + + 000102030405060708090a0b0c0d0e0f1011121314151617 + 00000000000000000000000000000001 + "" + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + 1c97d826583970d083cca433773b02c34c0e6b7127d2258435bac13100c8672db6084c02171ba72b9937b1daccd14d0db1c322c708cc2da13486d772d82d93d12b69874a220573fc25fc05922700228c475ddeae653855a2c6d5f563f6e0724b7b2fe0fa066cba3223e010c5d1a51301a2ae1047409ae88c2779967283d50aa40ebb93e07dbde704f39c76c20cd1e1970bab196eacebab67b076bf901b4ed6f6ff066e230b540737d6856472ac02dce8b7a92aaa8890a47a13fc01bbce7ff902e3a7ede4685cd9bb926fecc27e915ad900f248d7ddd3cb9bff1b589196740c35ecf330e3812a6e0fcd2fd32212b0f0515629e7165cfe64857ec5ca2ad5c6eed654e27508a2c012b726e6931c4edc1fc00dd1d609f8659b24c0b4157f43fc33761d0a9b1fb1389068b600ce2f04cf475fb4483d32902b559cc40a589e97a82417241b92199595c6597dbd0e8dc08db9b6c0323a1d07812908be90c7785c66d1b295ab772793dc7e9725ef19da40b935c6ce10e404165388db6437621ffb08246f32b85a7ee9ca8bec10e3e973136c0b99552d8713bc6c892938ad72f79341f16eaaa7c8adfe45e2c627314c256bf0554dc1651ca77a80d79603cec892ffa58b092b5134c61d6dfba2a2132c75ce56db8cb1d852330a5c4a615645281457c2020391351f8dfa1297d45da234c0549991046d888b52175e1ed2ed3619474b5b270d6b5dcdd94e1a3f20594da51c8bd564e9694cb8b498eedd7a83569da5a209ba34e0fb29c43793097437fecc07e7709c8d64f15197b241ee930652872558c7ccb8c2a0e61e40637d1d587422d5f9f8f8eb25e44f7997058c051c4288356e5dd47e6022176f83c963eac7512cabc7fc8c408d448177e1b1671c82569a2318db142f8b94a60fe5b581c6895e03397a4d9b6f117fb534ad644ef7fafab3fe34c36b5d1544df4567fa94ba7a501ed20032d567bfea10f943170e5bf9b1aac21c0e25ae5f9b98272c75a401ba0185e46ff0c9b29caeb2314a507e2664df2208beb8a5c78563f68b49c3b59b650d18eb75a22296d06943b99239521c59736a10404d458e80ed9288879545c1f9b997036b9eb76c5d75afcd494736971dd27c3f0cbdc15e8cf8337c63417f861a15c324b44fc8b3e4ef6a1924f470aefd0abb6a965451d13835e8a8d9ef94add1d2a41f42c6ebc55045d7a1c6bb0ea3af9560220180fa7b623cc2c44d5cace341746e80289e0b7321178d770e2043a5b02560328c1a01ec4ab64ff98de111c5be5516657cff2f88d3a02643a587903f28a7f9d76cceca8a03671eeecdb2aa81e59de1171e5aaae08415533ceee30aa3ec4fbd551990c074d05c390dfbb1e5d1318e869be9e8417d49ccdaf801ebd42b0309718c36deb2965311710b6d26494a + d28b89f5339444767d637e8f1687d204; + + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 00000000000000000000000000000001 + "" + "" + "" + 796b5fd2716b066932371c17993dcb5a; + + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 00000000000000000000000000000001 + "" + 000102 + a214d8 + e31b3449bd1b85b257b404a76b5b86f2; + + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f + 8ed0923f5b2c650f31a5dd422463377f + 794904f519ab5376a30cf7771548e319; + + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f10111213 + 6512529248df82feb506a7aeab3874f7201b6f79 + 042ac0fd6956c2b0b4205dba0b889699; + + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 6512529248df82feb506a7aeab3874f7742c85da9d0d6cc91293ce0b333e0343 + 6a91a07cb0bf508fee08b27b5fd9f80d; + + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 00000000000000000000000000000001 + "" + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021 + 6512529248df82feb506a7aeab3874f7ae809e2f4f88d6a6088f8d0122a7b9e723a5 + 3ba0661c8a716b550150c9effe3b773c; + + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 00000000000000000000000000000001 + "" + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + 1464d49f9ead864d5e77ed99198302409e459f2af179c73d2f0d0855d51591cbd9555d9a8542014e2b995e5399c1f804addaff1a2c4b5afe07fd88b7095d1129cbf93f9dad20c625fab0e63788ec4634f0ae06b6fc5c56bfe1b05860e03dc3284d7e2b3190eacee799f523677f942dee5192cfc6b5dddf09a16e2ae13055e9d1ee1d159b7fcea386133de34b92743caddef8c457884a7c5034a53ee23e08aa90086824401c25646561af0d594114b1ccb6627bff630fb17a6021b4f54942ed06f06326e54408019caba8f7231200d30dc548f8ec2c80e06b13d8ebe462c1cdf1c54065afabdb97ac8d8e5a1d065c59795fb55336f01e35a6f7cf8ddbf944e31a24717977c2f9f89aba3ca1ab7559a4f732d301b678ac63c9d5388665b1f9bc56bd67b80fe21f0d6ce4973c078213456b23700725174037fe8426503b0170ce5adda0dedc80f1e5d6701384951bbed58e6ec5912cd20429c5d85c61484136caa00c5f92763414e9f1bb50efc59c834142e5fbbab07f624f28fdee284c2b7322cf3e0682731f764a049fedf2ee8486e60bbd11de998f1dfde848999c806ef779bab0468b674d395883400cc6c05cdf5b51c5fbb181690502914edc42cd4752d9c5fb524adb37149c3199f2329ecaa92006047761f01581eafb96003491fef9ccdbf637c972842645b052ece338e02b6417e25f4f93aa808ec44d8b6efdd774ebac19a1756014a9bb71da38e7743d1617e44bae076f3183c7e50f5c0fd5488cb325edd500ad5e794c469b83a4655c95289dc520797f94cd04e834b1842f769236522cf79ae63ad4664b4745316142bc74ab27be915194eff2a2a1d740c83bffe28b8fe6cd1382ca8de806365275ed05baca90484b03ee87624f072905b69587c05be58aefd4e367257aa95ce3a6d0f65a5e7221c8f729727e3bd66f3d9e33f0d7b8f03ad31e62c837599e062a4c8681ec3276c31d58f2f3f2dd018b3c579fe50d7f911f8665bc064a08ae8ff6d87440e088b2162733ea6066ac70309600819f3f429232bb26376303fc82cd198dfc92382cfb3c8bc245984b845c51e6b5da8a9669e1d961f7182d0bb9757a99c0d72d4c037df2ca29661faf0db89fdce75bfb67031522096ce88f1ca6740f3dbbfd65fdf674a547d82d331abaaf1c5f0742a25c6f5ee0cfe288fb93e76d2fab4fde4904c2967303fcf2adb8bbd333b33728aca04b60dabdd08e0acafaffa97b02cb011db94687afa7bed3157d3a90814eb00e55b39cabfe9ef35bae62c80ad225cc34a0d7cce13c55ac107d00d7b37562222ac5d94cb73ff20d8947fb8ec63735280c0ce31aaca8fee02666f7a6fb2b44f1ebe0f090050f1036877ddb6705b1b622dbd1742f8ed2d985a5aeab4cd2a0e68d1ec3c6c1fec66446150d44 + 826d7f68f3ce28e1e98191e92b23ab0a; + + ## Homemade tests made with my toy implementation. + 60d7bcda163547d348b7551195e77022 + 907dd1dff7dac5c9941d26d0c6eb14ad + "" + "" + "" + bbdd78ab7b6ed33bfbaf8438bf9df7ee; + 568f86edd1dc9268eeee533285a6ed81 + 0c9b689daaa9060d2d4b6003062365b0 + a5 + "" + "" + f7922af46325a139e69abfbb9b999c4f; + 4364c76c160f11896c4794846ecfa14a + 7130c9f137120634c9519848a877ff77 + "" + bf + 98 + 8c5a791452eb9c1f37d7ab1bf637c432; + 79192a5b50ade5d9cd739a3d1f337f29 + 549e6b0d27a4ba234085406a61365120 + "" + 61f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9 + bed87d0e2b6ab736c20081f2041691cdcaedfff9cdb08f5ff2b443fbb4990690a9bb03b8b801d3562f037c61c6d40929 + bd5b4d2c9aeae8e9dd6baf02c53cc96d; + ff61cdbda3b3e9878731ebfedd4705e5 + 05da1435dceaa7b1cc49ae1d50c38201 + a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc + 520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605fae + b6cbe859f09a407e4a0e376a41b18a84eb07874e1b280fa3cdffa733c207c4b67ace2b90a406b1df6a2389593134796d + f370bf6c86cae4c4248040d74c191392; + e2b03fb648e27fff63102758fe2b69ac + 26afa3349829b94586306fed54154f8f + "" + 28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcb + 2ca95a4a033cd358788f8ffd43bbf820dc0982dfee8583eead310d571cb87e4472331362ff6820abf76cab3b4f405b41ad167f864d + e20d6b13e4691b43b82d5e16f77366b9; + aca48b77dba189196d1ebba10b0467cb + 9fc2712a199e533fa9156308cdec3f76 + 8281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95 + 214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063 + 8c3ebaaf931dd282e77df4bf8c242a81593282df72cf91df24dc0bd8f6559f404058b9885529821083839944713def901330eebe75 + 2d965094a4c93d801be22ba3faa198d9; + c46f88de9fd41e72d7b97e23e6eabdff3bcd2114 + 99268878dbf30f1dad89d4b9b12012e4 + "" + "" + "" + 8d524a5f17704ae5983de23c8c09fe82; + 713df46795630e7952d22bb02d7100b8b649377d + 20a8f083455b663e4ee1315f3c8f2aeb + fa + "" + "" + 9ea050885c272134d9056a4a94dba2dc; + 921451dcd1af5813b70d30ce2f1fef6ef315d079 + 8391805da08da3aefc5f8584b7c5e617 + "" + 66 + 93 + 813637682fa8878156badce86a0243fa; + 9c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb + 16c2e815f422cdf0c8e30308be3c31e6 + "" + bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446 + dd538bb0839a0a7925c5a2aaf2cac28de820d307023f2ab4f2ffa04cef224b155ab948ad399e65a9ea8477aea35f29e2 + e00806f1d623829ca51eeda7493528e9; + b42fb144d44b6d00f06dc188d472a784e0c6f211 + 95a3b9f4ae985511265febd11c164720 + eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a + 9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd1901073147 + 4a2e9698c0d7ac74177739a07570f0f6afd2e3f3b6e9badbdbd95fdfc747dbbc7c1c8bceb40e423e1b2fa560ed2da50d + f13efea41ebf09ce14655687cb20a908; + 17a77456f3ff669c732b58db8f48af65f7cc9e3f + b90e1721b730374ffc9bc597f56ccbb2 + "" + f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd + 672edb9395d87cc48fab9727017091e7a6d09f7977fbbfe77f9669485aaeca7a4d54662565aae03033ae925528e9880d33766cafcf + a8ff24657308e7d34115b33ff27ff795; + 1ff6778554acf1270485b203a3c1c4c967c0a458 + cb948bdd409b687fa3a6827b480aa3a4 + c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205c + dad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41 + 367a16e4adbc471e15eed3d0415714c61a67e93f44b5890d17f9d29991bae8406d317e7064c765278d7370f6534462f6eb2db66b23 + 79a7bbc9be788ebb4b94fe94f3f74439; + cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdc + ccd213e33f7e8a5718fd25014107c8e7 + "" + "" + "" + 12f235dbf2dc24a51ec9211ba16494bd; + d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9 + f891bc5ba5afabf8c3122d12d7ff3c41 + 12 + "" + "" + eb5d7e61788af1e2d62a0023cbee8ce8; + 2d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d669 + 9e6b7ea2725cb2dac07ecde95759ac46 + "" + fe + 65 + 80cbf647b155069f455e35ce699db1b6; + e6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9 + cf44bbc8c6254d980398bd94e66eb456 + "" + 3d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86 + 5b2913b5bd5d4155174de957631d366c398a890cdcdef62c8a7882229522d3b944a1b0cc2d958910469f001ff60f4d05 + fd4cff3dc0c58f0743b0bd9bc4e7b346; + 041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15 + ffaa6c36800d9645563a308ba6007681 + 7523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd + 56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b + 79b025b6d15120b9cc79ceb62cfe0479248b47f4b6318deeffe7ff11688460479331326370bac61dbec32ba5571d65d8 + ce1ea3a0bfda4a072c98376f259ed0d3; + 0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a9214 + 2b5b0677da1ac273117b45bcfff5d5f8 + "" + b6fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22 + 42075fba1b912e07c6f10e6356f6ccc84c60f34ea054dec4e4cdc39eb8f5066218b61d9cd799d28281e84d2d5f0138c944f1074b2a + 2889c19baf58c2061aa386bb60bf5c94; + ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0 + e80f678d404147842941feeffdc2eb44 + dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e241 + 4ebf47970e560475cff206877de69146acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391 + b270a45c7bb349e1dfbc9226da556d1916cb8eee0acc23671a875ba1bab176be7067e6ac38c492bef6c908881eed86e3fa34ba13bf + dd48047480fa2218d080933718dfa7dc; + b3f9d10c39b07ae8f08ce7ce + e4758a386a9943e97dedfbe61e737882 + "" + "" + "" + aec3dd3d7d4d41c121f6da813bc52c6f; + cd09c2b9a80f34c0fde11c24 + 81b11fc76bfa4dbf710a9e544e0c536c + a1 + "" + "" + 1fb81cfb59ee9a075fc17a01fb0acb9e; + e040f9ad5b04140d98edabe0 + 8485290a4d87d13b07398a1458c2c6b6 + "" + 1d + cc + 2efc465c99ba1057c7dce6bf82f04a7d; + bdbc1cccada8c1a0a9aabb6c + 4e3c3554f8fb1ef61614c270295dfc0c + "" + a6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae4 + c5b165d12e4f62edf355fad299ca25ee317c7c65deea43e27c93f43f66d87364b7dc60d20d5bcfde11e982c9275b2ebc + 5536fc1ce20b189e094233fed7a3da05; + 80cda98ad6cf2bacf6f9fd3f + 821330c43f3df6c2b3fac7cbcf96523d + 4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59e + d034a867642d25d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197 + 03cf2190ef314c60a1b51ab9c6d6cf1613779e05cb1f6dd1b54b16f1cebf6b964ee6f21a606b72e5751723d5ad6e284b + 7eb35f7458437efd2a95c97817396485; + a21cc34ac0d5ae7be8dbf98e + 4ffed2cf6b1372a5aa47b54fd9d70c70 + "" + e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1 + 8a8f9e2516855b74721de0ee915f1759ae9aa036c52d9cbe43111de9015eb6bd353bef5bb4df325f466d8e2bd09303f912bc0576be + c67bc656ea1b155208501e080120205b; + 406d465b7b1419ea51cf858f + 938f6daafbd656445a09898eaa96ffc3 + d1d2e31e4e34c94b8bfae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538 + e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a95 + 15d8d8bfdd4b5fbe0885d060fc15bb2763c2d4aad2d18df548ed258db51d9cfd866b4e7798650061e447291f45ebe5da37635d468d + 329d67984dc92e926bf2c0698fba9e2b; +} + +rijndael-pmac1 { + ## Rogaway's tests, from http://web.cs.ucdavis.edu/~rogaway/ocb/pmac-test.htm + 000102030405060708090a0b0c0d0e0f + "" + 4399572cd6ea5341b8d35876a7098af7; + 000102030405060708090a0b0c0d0e0f + 000102 + 256ba5193c1b991b4df0c51f388a9e27; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + ebbd822fa458daf6dfdad7c27da76338; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f10111213 + 0412ca150bbf79058d8c75a58c993f55; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + e97ac04e9e5e3399ce5355cd7407bc75; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021 + 5cba7d5eb24f7c86ccc54604e53d5512; + 000102030405060708090a0b0c0d0e0f + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + c2c9fa1d9985f6f0d2aff915a0e8d910; + 000102030405060708090a0b0c0d0e0f1011121314151617 + "" + 0d63b2b2c276de9306b2f37e36dabe49; + 000102030405060708090a0b0c0d0e0f1011121314151617 + 000102 + 5b1cbc4340752742d8828a7aa2c3197d; + 000102030405060708090a0b0c0d0e0f1011121314151617 + 000102030405060708090a0b0c0d0e0f + 0787415737989bc1a2e124c991e400e1; + 000102030405060708090a0b0c0d0e0f1011121314151617 + 000102030405060708090a0b0c0d0e0f10111213 + 156a7c21121cc773a731e05ab618c6bb; + 000102030405060708090a0b0c0d0e0f1011121314151617 + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 654a145904dc97da9f68318b180970b9; + 000102030405060708090a0b0c0d0e0f1011121314151617 + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021 + b5ff2016878e834438aa1ff624bfa09c; + 000102030405060708090a0b0c0d0e0f1011121314151617 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + d3aec29036298bc11a2905f53773ff50; + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + "" + e620f52fe75bbe87ab758c0624943d8b; + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 000102 + ffe124cc152cfb2bf1ef5409333c1c9a; + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 000102030405060708090a0b0c0d0e0f + 853fdbf3f91dcd36380d698a64770bab; + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 000102030405060708090a0b0c0d0e0f10111213 + 7711395fbe9dec19861aeb96e052cd1b; + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 08fa25c28678c84d383130653e77f4c0; + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021 + edd8a05f4b66761f9eee4feb4ed0c3a1; + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + 69aa77f231eb0cdff960f5561d29a96e; + + ## Homemade tests made with my toy implementation. + 60d7bcda163547d348b7551195e77022 + "" + f179b2c8e7020f9992e161128568d833; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + 335ab1737aaadac9f7d949ab7dc22fb5; + 8f86edd1dc9268eeee533285a6ed810c + 9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77 + bb8edccea3819962f3207d2494d63229; + bf79192a5b50ade5d9cd739a3d1f337f + 29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21 + 2ecd8200722cfe2378e956131b67d64e; + 635c6d62c9269029df3e6057acc87638f5080467 + "" + 5defdf6083418cf3d45824aa490a4d81; + 33d9ff61cdbda3b3e9878731ebfedd4705e505da + 14 + 6c60b9db748a6bdda7823422ed13e4cb; + 35dceaa7b1cc49ae1d50c38201a894476b3f102b + 752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3 + c20cac43be40631325f8d7c9e65991ad; + a4f3ebbbb18ac6c95a97a48030370c33d090c542 + 15abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829 + 3c963d5d3230ef4dc33ebd19f63965d9; + b94586306fed54154f8f28523c03d4de1600157846b710ee72807a22 + "" + 050092b5cc9a2d131ea4450c057bbf3d; + 19bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d + 42 + 16501f8ba884f8ace15138cefd2639a7; + f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e + 533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5c + 9738377d0ead6012bac60ae10ac4e5f7; + fb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc81517 + 84873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6 + 709f56ce90034a8882bebbfe453452c7; + eabdff3bcd211499268878db + "" + 697879320c2ee020acf13693df75c31d; + f30f1dad89d4b9b12012e471 + 3d + 453c840a1c34bfeff73a653ad97150b4; + f46795630e7952d22bb02d71 + 00b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da0 + aef316f092694e691d9fba0324d8397a; + 8da3aefc5f8584b7c5e61766 + 9c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb6 + 0638371148ba4e00b0cf138e026a7740; +} + +rijndael-ocb2 { + ## Taken from https://tools.ietf.org/html/draft-krovetz-ocb-00. + + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + "" + "" + "" + bf3108130773ad5ec70ec69e7875a7b0; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + "" + 0001020304050607 + c636b3a868f429bb + a45f5fdea5c088d1d7c8be37cabc8c5c; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + "" + 000102030405060708090a0b0c0d0e0f + 52e48f5d19fe2d9869f0c4a4b3d2be57 + f7ee49ae7aa5b5e6645db6b3966136f9; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + "" + 000102030405060708090a0b0c0d0e0f1011121314151617 + f75d6bc8b4dc8d66b836a2b08b32a636cc579e145d323beb + a1a50f822819d6e0a216784ac24ac84c; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + "" + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + f75d6bc8b4dc8d66b836a2b08b32a636cec3c555037571709da25e1bb0421a27 + 09ca6c73f0b5c6c5fd587122d75f2aa3; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + "" + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627 + f75d6bc8b4dc8d66b836a2b08b32a6369f1cd3c5228d79fd6c267f5f6aa7b231c7dfb9d59951ae9c + 9db0cdf880f73e3e10d4eb3217766688; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + 0001020304050607 + 0001020304050607 + c636b3a868f429bb + 8d059589ec3b6ac00ca31624bc3af2c6; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + 52e48f5d19fe2d9869f0c4a4b3d2be57 + 4da4391bcac39d278c7a3f1fd39041e6; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f1011121314151617 + 000102030405060708090a0b0c0d0e0f1011121314151617 + f75d6bc8b4dc8d66b836a2b08b32a636cc579e145d323beb + 24b9ac3b9574d2202678e439d150f633; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + f75d6bc8b4dc8d66b836a2b08b32a636cec3c555037571709da25e1bb0421a27 + 41a977c91d66f62c1e1fc30bc93823ca; + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627 + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627 + f75d6bc8b4dc8d66b836a2b08b32a6369f1cd3c5228d79fd6c267f5f6aa7b231c7dfb9d59951ae9c + 65a92715a028acd4ae6aff4bfaa0d396; +} + +rijndael-ocb3 { + ## Taken from RFC7253. + + 000102030405060708090a0b0c0d0e0f + bbaa99887766554433221100 + "" + "" + "" + 785407bfffc8ad9edcc5520ac9111ee6; + 000102030405060708090a0b0c0d0e0f + bbaa99887766554433221101 + 0001020304050607 + 0001020304050607 + 6820b3657b6f615a + 5725bda0d3b4eb3a257c9af1f8f03009; + 000102030405060708090a0b0c0d0e0f + bbaa99887766554433221102 + 0001020304050607 + "" + "" + 81017f8203f081277152fade694a0a00; + 000102030405060708090a0b0c0d0e0f + bbaa99887766554433221103 + "" + 0001020304050607 + 45dd69f8f5aae724 + 14054cd1f35d82760b2cd00d2f99bfa9; + 000102030405060708090a0b0c0d0e0f + bbaa99887766554433221104 + 000102030405060708090a0b0c0d0e0f + 000102030405060708090a0b0c0d0e0f + 571d535b60b277188be5147170a9a22c + 3ad7a4ff3835b8c5701c1ccec8fc3358; + 000102030405060708090a0b0c0d0e0f + bbaa99887766554433221105 + 000102030405060708090a0b0c0d0e0f + "" + "" + 8cf761b6902ef764462ad86498ca6b97; + 000102030405060708090a0b0c0d0e0f + bbaa99887766554433221106 + "" + 000102030405060708090a0b0c0d0e0f + 5ce88ec2e0692706a915c00aeb8b2396 + f40e1c743f52436bdf06d8fa1eca343d; + 000102030405060708090a0b0c0d0e0f + bbaa99887766554433221107 + 000102030405060708090a0b0c0d0e0f1011121314151617 + 000102030405060708090a0b0c0d0e0f1011121314151617 + 1ca2207308c87c010756104d8840ce1952f09673a448a122 + c92c62241051f57356d7f3c90bb0e07f; + 000102030405060708090a0b0c0d0e0f + bbaa99887766554433221108 + 000102030405060708090a0b0c0d0e0f1011121314151617 + "" + "" + 6dc225a071fc1b9f7c69f93b0f1e10de; + 000102030405060708090a0b0c0d0e0f + bbaa99887766554433221109 + "" + 000102030405060708090a0b0c0d0e0f1011121314151617 + 221bd0de7fa6fe993eccd769460a0af2d6cded0c395b1c3c + e725f32494b9f914d85c0b1eb38357ff; + 000102030405060708090a0b0c0d0e0f + bbaa9988776655443322110a + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + bd6f6c496201c69296c11efd138a467abd3c707924b964deaffc40319af5a485 + 40fbba186c5553c68ad9f592a79a4240; + 000102030405060708090a0b0c0d0e0f + bbaa9988776655443322110b + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + "" + "" + fe80690bee8a485d11f32965bc9d2a32; + 000102030405060708090a0b0c0d0e0f + bbaa9988776655443322110c + "" + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + 2942bfc773bda23cabc6acfd9bfd5835bd300f0973792ef46040c53f1432bcdf + b5e1dde3bc18a5f840b52e653444d5df; + 000102030405060708090a0b0c0d0e0f + bbaa9988776655443322110d + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627 + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627 + d5ca91748410c1751ff8a2f618255b68a0a12e093ff454606e59f9c1d0ddc54b65e8628e568bad7a + ed07ba06a4a69483a7035490c5769e60; + 000102030405060708090a0b0c0d0e0f + bbaa9988776655443322110e + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627 + "" + "" + c5cd9d1850c141e358649994ee701b68; + 000102030405060708090a0b0c0d0e0f + bbaa9988776655443322110f + "" + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627 + 4412923493c57d5de0d700f753cce0d1d2d95060122e9f15a5ddbfc5787e50b5cc55ee507bcb084e + 479ad363ac366b95a98ca5f3000b1479; + + 0f0e0d0c0b0a09080706050403020100 + bbaa9988776655443322110d + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627 + 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627 + 1792a4e31e0755fb03e31b22116e6c2ddf9efd6e33d536f1a0124b0a55bae884ed93481529c76b6a + d0c515f4d1cdd4fdac4f02aa; + + ## More tests, made with the toy Python implementation. + 60d7bcda163547d348b7551195e77022 + 907dd1dff7dac5c9941d26d0c6eb + "" + "" + "" + 7d2702e740fddada3e57a788402f9d44; + 14ad568f86edd1dc9268eeee533285a6 + ed810c9b689daaa9060d2d4b6003 + 06 + "" + "" + c129582b8bd54dd2e80592f467112495; + 2365b0a54364c76c160f11896c479484 + 6ecfa14a7130c9f137120634c951 + "" + 98 + 8e + 27a9a3f75d1f36a156c714d820d0b3ed; + 48a877ff77bf79192a5b50ade5d9cd73 + 9a3d1f337f29549e6b0d27 + "" + a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e60 + fb544221d7bde1ec31564a9580440c902d76a7df1eff12955d17995e9bfe2336d4c2eeb42a6656dd37200ce5ff9cabfe + 0f9ff860aba97bfab2845af16558883f; + 57acc87638f508046733d9ff61cdbda3 + b3e9878731ebfedd4705e505da + 1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa4 + 50727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54ef + 08584d252daf79311ca8d694e33e04711f723c890a222e7ce75ff2842e87e39d714934e8c6dc3640ffc5cdad1634063c + 679f104fe67c507aec33a0e15b589bc2; + c9a38378c5b93bf4f2aad2605faee2b0 + 3fb648e27fff63102758fe2b69ac + "" + 26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b + 63c2bf2254c696b288b0f41fb5b44bdf45914dce25d0071438069dbff337bc844506e5a47a28c700500280c08c54a5e4b43118ce36 + b9fde958caee8ea9cdbe8425ddb382ad; + 571ea629c54d57dd2d42f70800df9fcb + aca48b77dba189196d1ebba10b04 + 67cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a2226 + 0c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b + a459d6659d827b523dabbc0a66cf8c151764b24a59199a6d8e4a161ace110c683dee759f823be08f0538fce282d036d2c7653ecb91 + 63bec719103775440457715faa831368; + 5337685a96ed65b9aca338527ef19b09c063c46f + 88de9fd41e72d7b97e23e6eabdff + "" + "" + "" + cc2b3f40254925c2e221259c3b6e8df2; + 3bcd211499268878dbf30f1dad89d4b9b12012e4 + 713df46795630e7952d22bb02d71 + 00 + "" + "" + 272e89e7297e08da41d775d62b336e80; + b8b649377d20a8f083455b663e4ee1315f3c8f2a + ebfa921451dcd1af5813b70d30ce + "" + 2f + cd + 3c1a46e21f59810999d3ef51f0460322; + 1fef6ef315d0798391805da08da3aefc5f8584b7 + c5e617669c0f16e39815d4 + "" + e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69 + b75d269e9b2a080fd4d34bf0f8e7007e289b3f84ae1b8b6635fe27c5121605f12ab038a2fdfe7e29128beb944fe01b4f + 0e98f9a81eb34cde7f67bf40e05b6058; + a4cd52147ed12ca986981a874498ad0abef8bc4f + cb70e27e98ef1f0446b42fb144 + d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00 + 456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6 + a4b540f15bcf54450c71860ffb180accc2b9218e4780a80b11cda67f1c38c8a9a8b0c5d42b243c5007b1832868dc1212 + 9fdcf861176e933b53461b27aa00e837; + daa089c3f9099c5ffb824173d7634c04226f30cb + b7f0e4a973a8cd190107314717a7 + "" + 7456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0c + 9897c9d1b74b1f19e984b37cfb2823670e662d5b26bc7216a174fe2bdc87b7ae8e76f57b71cf8ef83d9f7da96a5f470d6b29b62f06 + cf1f7c7135e2f593a2b66800fbf07ee8; + ae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f + 0911e32d65cc1770a18cbfe6effd + 1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b5 + 3bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451 + 7df3a815613704e6db80308c5e5161430a724f4a11dee60f9b0519f96f29c8c6fcf91443f230d7ee8fd8206e0c71161e9d770d5586 + e54a174b4a61d1ee1faffa2dd7a59f70; + 399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65ba + d397abfaf529ee41cf9a05c7efed + "" + "" + "" + 74e3172048a0aed02ad958e79920884b; + ef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e + 8a5718fd25014107c8e7d715a92a + dd + "" + "" + 148ca2d47df2264f1aba1b2b374aad1a; + 9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5 + afabf8c3122d12d7ff3c41122d70 + "" + d1 + f5 + 4c185af3fa049730ff516d35fbda064d; + 7d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7e + a2725cb2dac07ecde95759 + "" + ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d + 64e99a93b20ce72c4e9da3b335e722e85aeb922ace51720c32f4edb402571244d7d1e4f3d2bae1baa06da5ec6d7368ec + bd4509f46b03609bd11124376731fa19; + 405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b954 + 60938de1288c69d80ea12ff4bb + 5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba600 + 76817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973 + ede69717cc474d94579f3aa442ecb523504280aa8dfb5604e81f8f18c5aee67140400e27ee7aa624cc3d2f8bd8eb1dc8 + e3472e0b88ee37919d72e8a29553274d; + accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f0 + 9e7a10fc02a8f48afa3080ee119a + "" + 52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6 + 6ea42fed3a9e40ae5bd32e3513e027f791595675af5e77e0044070af2ce0ca4e1facf77f6b7f0c16b2c3c528343a9c7c6d1352517e + 476ce6884dfa2a97ce67aafcc3375ea6; + fde2893232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2d + d721c0095c8808847689211450ba + 8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d40 + 4147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2 + 17fa00469b04d4b9563e87be4bd5f9cffd0238adb9ee98938dabb0528e0fa95fc3cf499e67d4d19606242736d8e776bd5357a0d48c + c8ef4f4fccad46f7fb55786818991586; + 414ebf47970e560475cff206 + 877de69146acc3ab6cf8556b7aa7 + "" + "" + "" + 17c75f5f7d6d099a7d375b9ea6ee9fc6; + 76945948d1b8834df2196c92 + ec1718dcdeee0d52d9539726d281 + 03 + "" + "" + 2abbc7c4cac1b870f9e8a92f00f1f2f9; + 91b3f9d10c39b07ae8f08ce7 + cee4758a386a9943e97dedfbe61e + "" + 73 + f4 + 8ab448b5400b1a46c7c5e20ef9700e22; + 7882cd09c2b9a80f34c0fde1 + 1c2481b11fc76bfa4dbf71 + "" + 0a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb + 7c8660ca8ca219cd98abe715c166df757edad193c7d1a6f9227d7633b1666bd34c86f6df7819a80903e5c37ffc5e0648 + 27c846118776e3626f15532888d3f887; + 6c4e3c3554f8fb1ef61614c2 + 70295dfc0ca6551ca4bdb75359 + f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bac + f6f9fd3f821330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98 + 9c912ef9d07d26881c823aecb92e81cc988fbdd1292d49ae9cddc5c1fa5e1a618c96e71c64866481926bc83c1c2ec172 + b7f45c7b104609fc3be061ebb388ee13; + cedbe88e245de25b1593b70f + 8601562d90a9b59ed034a867642d + "" + 25d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf9 + 00bfa16e1410e13d46752a90f40b6d9f6193cf06930ecb55abd2f973b710fa0582b30f87e5edc850a652def300f06da79231471399 + b8858413846d2de7fa4654376b1b9f1f; + 8e4ffed2cf6b1372a5aa47b5 + 4fd9d70c70e117bf1cae71b3a56f + 0e7d839ea59cc783443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597 + a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae64825ecd75a66d88eedb969ffe0 + 9cadbe9441f1705005b73f4e5b1675fc77390306e768a3f599a8fb11846ec535f0fa52e88120d3409912c342401b16a395784c6dcc + 44773033baea19b7a13cfe0f67d9da85; +} + +rijndael-ocb3-mct { + 32 d90eb8e9c977c88b79dd793d7ffa161c; + 28 a3c8ceaa94b405effc970e05f15fa2ff; + 24 f673f2c3e7174aae7bae986ca9f29e17; + 20 c8bc484858c5b1bc9e4241e2f552b371; + 16 67e944d23256c5e0b6c61fa22fdf1ea2; + 12 2e9806312d331fe78476fe88afb74763; + 8 2cfce691258f4d0300c220a6ef4d0a81; + 4 5d36742a2f065dc845789585f81f052f; + 32 5458359ac23b0cba9e6330dd; + 28 a14417b0bad703c8d1eccd2e; + 24 05d56ead2752c86be6932c5e; + 20 a61001205f451947258a950d; + 16 77a3d8e73589158d25d01209; + 12 6a32e20692f16b31a51cff6d; + 8 211b29176d56d0528fd70c9f; + 4 db638b2ddc074fe1ec1056d3; + 32 7d4ea5d445501cbe; + 28 94d6f38a6bcf4fa0; + 24 0066bc6e0ef34e24; + 20 1a583bc011e8a4fc; + 16 192c9b7bd90ba06a; + 12 385bcd58e8387991; + 8 2fb22e566436473d; + 4 c00b55e9a2bed310; +} diff --git a/symm/t/rijndael192 b/symm/t/rijndael192 index d7732ff5..4210f737 100644 --- a/symm/t/rijndael192 +++ b/symm/t/rijndael192 @@ -2882,3 +2882,931 @@ rijndael192 { df6e46c2dbf69f357bbe22bf604efca58a7352a18f41a7ad 1d5fa8d85dc2428dabb69eb4c9cea7180f2fa554eadb9dc4; } + +rijndael192-cmac { + 60d7bcda163547d348b7551195e77022 + "" + 60b69a71abf68553087a4635c8f3d6a6445330a424fcd5bc; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + a70f592cc5ea00d17b15fa9810fd694c21e9df121ef3b4b4; + 8f86edd1dc9268eeee533285a6ed810c + 9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba + 872bf13b5f881a915c9342329f04911369c818c0ea171840; + 234085406a6136512061f7080cc07df0 + 591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49 + 8b456186aa6c2a0d7595f606dc18e4934435f659d05d8994; + ae1d50c38201a894476b3f102b752eb952953396 + "" + 2d401a31a7641d7793074c1fd8f49be54d4b542aaefaa85b; + 6f27043eb621b7f65b000961040ef2f9b2fc5fa4 + 50 + f6433b85e1c5134170efabaf9787fbd7e65cb12ce129d440; + 727a9b542cde52ebfda19d0ccc520f215eb57bb3 + a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f + 20c4e9333e614096c96a21d83ef6779616d99f93167fd455; + 8f28523c03d4de1600157846b710ee72807a2219 + bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f7682 + a7ae91664738b763e5d45d556edd0b59923f159dc9cea08f; + 81e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a + "" + 558b741080d1a886fd8798f4100853f2004201a48be08907; + 42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c + 03 + e115710b82135a9cbc43aefae273556dcfb62394c78417a6; + 7ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9 + aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b + 22ac79b7ae3011dc8a14b3516edadac8de849d9599fefa6c; + 663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef3 + 15d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e4 + 57c8bb706e09c6ac44146a999925abef54403c8e610efca4; + 7479a684b5aefa69a4cd5214 + "" + afde241e1a29decdd2f924776073a7108b90a02528d9db4a; + 7ed12ca986981a874498ad0a + be + 37beddab340f4b5245afc8b5a0fd78004ffcdbdd2f3a41e5; + f8bc4fcb70e27e98ef1f0446 + b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc3990844 + 4d27aa546ff3594eeaf076a140cf3e38686d4d9b2d9f75b5; + 5608fe95e81c2533e31c9c1a + 9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e + 3848a7fc35a38ec5c202692eb9cc03067f1e3a587996a2fe; +} + +rijndael192-ccm { + 60d7bcda163547d348b7551195e77022 + 907dd1dff7dac5c9941d26d0c6eb14ad568f86 + "" + "" + "" + eb328a4c; + edd1dc9268eeee533285a6ed810c9b68 + 9daaa9060d2d4b6003062365b0a54364c76c16 + 0f + "" + "" + b2ac3bb1; + 11896c4794846ecfa14a7130c9f13712 + 0634c9519848a877ff77bf79192a5b50ade5d9 + "" + cd + d3 + 2fe24f74; + 739a3d1f337f29549e6b0d27a4ba2340 + 85406a6136512061f7080cc07d + f0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c3 + 8201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c + 6d7e47a271f0a9140ab83f9874698af802509e3ce08ae633274ec72ba7fc0439a766245ae5ea7e1581432240c5e9400e5d4da1d9f3ab8d203cf35bbc9bdc48354be9ab81d3c97197 + fa0923d87206b84258099d69261e1f86f7da4740051c5087; + 33d090c54215abd6b3ad54efc9a38378 + c5b93bf4f2aad2605faee2b03f + b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b57 + 1ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42 + 3fc60a985fd9a0b75ff268e4dbf8c87195dcd97029ed59b6a8592fac9a954fd250025e1cb3fb3c7d509e327ceedf08d3c90467a66f23c7a45369ce96c0450e44b09434979c7962c4485c2b2bbf + 54ae41dbd56b7171107397fa7f4aa3a81f889a179161bcee; + bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f + 5fe8368131115c037ba323fe1dc8151784873f + "" + "" + "" + b65bbb04; + 0eb5b647da6794c18b5337685a96ed65b9aca338 + 527ef19b09c063c46f88de9fd41e72d7b97e23 + e6 + "" + "" + d1f9ef31; + eabdff3bcd211499268878dbf30f1dad89d4b9b1 + 2012e4713df46795630e7952d22bb02d7100b8 + "" + b6 + f8 + 3b797ce2; + 49377d20a8f083455b663e4ee1315f3c8f2aebfa + 921451dcd1af5813b70d30ce2f + 1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e474 + 79a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720 + 7b80a5b2f5259f81e3e755ac7afcaf2dfc39714c0b17a69c8a126fcf854ce88936114c5309af3ebc4d06437399884d56edcd0d5d89c0106326b3f801ac391c6ecfd167efc7d1b7d7 + 4b5a71ab534a4ae72dd6709be87c69173467728ed407de1f; + eef9eb1c8dd0b00951f284649016ed0045633185 + 4bc78bf43966eb0cfa9138ddc3 + 9908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456 + f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc + 24d3d61a7ec5951c8e7687bf216082e306d71c7a9351d45e7272418a2e4a22c8d5f5255abc0f1f081919b0910596727bc3ac57f0f4e55d562144ea20ccac5c640ea08baf53f71e35faaa8d75f0 + 65337469537455c0488f31bdad41f2bd174c2b890dad1d33; + 1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458 + cb948bdd409b687fa3a6827b480aa3a4c84cef + "" + "" + "" + 773f8182; + 64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8 + deb9bd205b70e04c091d205cdad9e9a79b1abf + 91 + "" + "" + 1bad4133; + b0851e5ca605ac8451399587011677508a15dde524af3e2bee064654 + 1a42c2ecccb44d65bad397abfaf529ee41cf9a + "" + 05 + 41 + fdcd5753; + c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213 + e33f7e8a5718fd25014107c8e7 + d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6 + 699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8a + 7f1ac5936bacdff5ab2339c74028aedc3266926aaa6685e9b688b5ac499d1a6912f4c957dbad07dc747ea4b9855f7656fd6952cbddb4a0296cf2e58227e0c05fad7d373f3a6a081f + bc33380a30663863f7d96afb80b51b7e89b08bbe5d523f62; + b9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80e + a12ff4bb5f069b8a2e86041c1b + 9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc6 + 67a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cf + 055eaaabcac3b8d64c9d744eb534ea4259d6c114554cf28dee96aa729da5b70556f4a9a8724506b42fe6b2d266db7cd0b904881f7dcd312ea17e9d256e14fc40d8d6a6286cbcc3772cb3c79f25 + 72c96466655bf5d891fab5d415bc6065d3902ca0b8f95a40; + feea7c486315799dc875fba5 + 78c8ec4837898a92142b5b0677da1ac273117b + "" + "" + "" + bcaf4c92; + 45bcfff5d5f8b6fde2893232 + a9f81d14517ffae475f6b94a43a67b3d380d2f + 9a + "" + "" + 25f9961e; + aafe2dd721c0095c88088476 + 89211450ba8095ffab1eaadf66fd22ac197606 + "" + 3e + 10 + e0be6bf8; + 113ab61f813e28a1397a7974 + a1d7f4220c785fe426a5a0e80f + 678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de691 + 46acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f + 633bd657368c964b774d76c9a8deef5e79c2db8c3ba300ff01b9a1685cb5688f8477c50bf62f380d5dcbf7e9fef05b73415e446f8675dcbd02c9a182b3647d7fc7e5320b9fc480bb + f3a1b675f8b96ce151ef507f6a587f4f9d78db3df352eef2; + 34c0fde11c2481b11fc76bfa + 4dbf710a9e544e0c536ca1e040 + f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d9 + 21056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c + 77d68b7c74c11fa6f23cab03c8e20965e7362191f15a359371f06954d0a8673d43d291db49563e5775d590a5b66a4de2c79fa96da0bbe7b18ff98fadead8cdc6bf8f559ed3675d46cca4cb27f3 + 828d1b75c068055451d00b6a0e8a5b0e5672f780c282a170; +} + +rijndael192-eax { + 60d7bcda163547d348b7551195e77022 + "" + "" + "" + "" + 4f06617fd2435935d07da73b3fa4147dac1325a119046009; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + "" + "" + "" + 91538eab427977388accbffddc6478f21b5fecbc6c7cb90a; + 8f86edd1dc9268eeee533285a6ed810c + "" + 9b + "" + "" + e5c24c4b113407583e10b409e553d653a5a519cba5f6d500; + 689daaa9060d2d4b6003062365b0a543 + "" + "" + 64 + b2 + 04d4d6804877ab6f6b3fa8566da51a683626144b1f15b0c9; + c76c160f11896c4794846ecfa14a7130 + c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd + 739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff + 61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde + 5ab0c81553820168ce731c21e2d27c369cee4e9e62ad20e90f838e1e625efa976022de1063b1eea5f4b80f436fa05ff63b8805ccffe979d6d3809360b85598694b0e56f834aa44d6 + 4808e60011165622ccfea271b2720944612f7ba9fdaeff2b; + 52ebfda19d0ccc520f215eb57bb3a4f3 + ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad + 54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219 + bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689a + f741602c2f1d8e46421651f6022a8c5525619a3231ccc623aa9220867f029b7fb8ded5cf9ecd06524d68399fad71cff1f9e3ec8b384d0eaa143f69593400261ad9bcb746d9be5dd613118b6448 + bb31af3207c2cabea82345be05be7fdf5198225ca65e71ed; + ef66f5306ceb0c6b08ac8b0a22260c571b4a42bb + "" + "" + "" + "" + 9f2973f4e855065a8d48db995fb178a141518b2737ac40d3; + 8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5f + e8 + "" + "" + "" + 44295827bbc06d0fd366f80689343bff188759f2cd39683c; + 368131115c037ba323fe1dc8151784873f0eb5b6 + "" + 47 + "" + "" + bc4ca9743e53d5cc9fae593892c0ce36d6a7d08547cfe2ed; + da6794c18b5337685a96ed65b9aca338527ef19b + "" + "" + 09 + 7c + dec701d10c4fdb386ca3d6546339bc1f896eaf2ab62fcc63; + c063c46f88de9fd41e72d7b97e23e6eabdff3bcd + 211499268878dbf30f1dad89d4b9b12012e4713df4679563 + 0e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e3 + 9815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb + 0d0020cb99818864e1a42510c9f02fa9d8e1b7eeece9e2a47aee82a256d573aa3b4fc5e71b7bb3c728e738eb84efe398a767378611a9c567ddd1f2d1dde0542273f61eb745d20483 + 2370d3c0afd70bc36b3bf48b066e6a669bb6421d7c96f5a3; + 70e27e98ef1f0446b42fb144d44b6d00f06dc188 + d472a784e0c6f21195a3b9f4ae985511265febd11c1647 + 20eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa0 + 89c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0 + 8c2e22689dfa878356ce69e873da970dfdacb405aab70851448ceb62ba02cb110d425683508f8575dda4f95545df5db12e04bffcf5b81c5b83a4ba6e5dffa6421f513791b59152f2e102afefe2 + 3e1b8d85bd6ac24ef82725ef0240e33f237223e26aff80ee; + 945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f + "" + "" + "" + "" + 75e5558c9504d6207f55489f4884c98abb6e0beec7a95435; + 0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1 + c4 + "" + "" + "" + e39471f2d0b80ffcb2dbd929c96ae456486b7d8b3f11876e; + c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b5 + "" + 3b + "" + "" + 6b3580a5ea32ba95c99712d167ca737628592fea8e2e2b99; + f8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b + "" + "" + 70 + 01 + 124d761a70529ba540c4a3fdc8f027dbb1795a730ad5e11a; + e04c091d205cdad9e9a79b1abf91b0851e5ca605ac84513995870116 + 77508a15dde524af3e2bee0646541a42c2ecccb44d65bad3 + 97abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294 + a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7 + 9f006d1fa01a0740b164f5e4c14a110cf20206a44206cd847498c555a495fb07fbb62f35082ec3303cc08298c364656b41c741318162786b2fe494e6cde8b670e64ef492de01027f + 712accd8ada4c4492c6fa2357c801ea07cb16b55179e2a5d; + abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bb + c8c6254d980398bd94e66eb4563d405e51881e99027b8a + b9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ff + aa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4 + 7a12401a5a74a3791b3fea7958393230536885a7761e3716e36c2b571bf9510dc268dd30a4faded0794addc797a0661b6d485a4ed2c50ecefd4932e615ab6cc4c9180bcd5491541475508f873d + 22a1b541c2b7a784bcaaf00680273feb1a93c187e601413a; + fa8fec816ac861a8b33779f0 + "" + "" + "" + "" + e78606fd15a8ba1222d2f85ece0d3a66618ad8308820fdc9; + 9e7a10fc02a8f48afa3080ee + 11 + "" + "" + "" + 2a1684ea67082c34418df0f0d2366cfc1080b493930feaec; + 9a52a9a817e4f2b94b0820ca + "" + b3 + "" + "" + 83c2f7ecef5d874db22c51272440484a8fcd0b3beb84761c; + 83a8cffeea7c486315799dc8 + "" + "" + 75 + 1c + 1d96631473b4223491a78b3e90f91223dff32d90811433d3; + fba578c8ec4837898a92142b + 5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d + 14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0 + e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877d + 7daf1f5c982d561f22d520d3a528bdc16ea98a48c641b6314b0cd5c6da05f6bc6f3519be0a2c81177e44de266afa4f62b72d9c2800c039115ab81b671d940e314f1edaabe7685aec + e7d163d20f75659b4b0fa2b150abfabd0e1a83a4d5903a20; + e69146acc3ab6cf8556b7aa7 + 76945948d1b8834df2196c92ec1718dcdeee0d52d95397 + 26d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b + 04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c + f2a5115aa965c209277a24b0c325ce806520f4725aba623a5edd757c9b8ae4da2f4e918ceb2ba756bea2b7e16ce28cd808151ff29ea78c662ddaf739313c5930e2859da808369301b81db91309 + 77613f8246951823e51a3370da0344a58531540bafeded71; +} + +rijndael192-gcm { + 60d7bcda163547d348b7551195e77022 + "" + "" + "" + "" + 015da0e6189d029fc8dafe862408dcabc30fda92fc68e1ad; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + "" + "" + "" + c932ffe01a259789c15ce089d5f8b7ea68f802ad4f95d278; + 8f86edd1dc9268eeee533285a6ed810c + "" + 9b + "" + "" + f00e7ec01693132f470761f98c38f8059d68abf0f24619cc; + 689daaa9060d2d4b6003062365b0a543 + "" + "" + 64 + 10 + fe5372d9b2db602ba2611ebc0100bce5c00bbed04792cb05; + c76c160f11896c4794846ecfa14a7130 + c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd + 739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff + 61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde + c59a7b60e5c4237f3c10e9cde0219aa4099ef7c0323b9b6a2b9c403327510e8966c95884af2892e93562b24c97711b08dcd6d3f96cd6ef4a4965ea599ce6483cc8cc7b356ed79aa4 + 5ce6dffcc1adf4308013c22d19323d83025c0f821b25bf4e; + 52ebfda19d0ccc520f215eb57bb3a4f3 + ebbbb18ac6c95a97a48030370c33d090c54215ab + d6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff + 63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77 + c82c8f3a0ce6dcaefdb53e2e831e9192559ce8c45c1967f5a9ef2f3ec68b94c9c2206a606c318d53ffe10e195a5d3ad88a866976d18550e9e13e6d3df6954b675eda0b433bc4bf78a46eb25038c4c1e1a6 + e2203c3246cd4609749431f291149ec7359c6c1f98316738; + dba189196d1ebba10b0467cb9fc2712a + 199e533fa9156308cdec3f768281e040a9b9a222bd689a + ef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b + 5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f0 + e4e1aa2a9dc0ecadfab0d06a51cc52bc051eece169d640ea09e5ecbc5132389d823bf160bc0c3fd935be0a07b7350bf34aae3a6e93aa874aa8df85949f3ffce3ad63b63d972067f2ffb42da610 + 033ee0ffd59a68e6c64bcf376e1b4b5c3b55b704af3efd30; + 83455b663e4ee1315f3c8f2aebfa921451dcd1af + "" + "" + "" + "" + 11162ce42451687d06c7ea1d05f235a12f8c1dec59f7ffb9; + 5813b70d30ce2f1fef6ef315d0798391805da08d + a3 + "" + "" + "" + c9f80fcab02986639b9e1f4240582daf41b51a065bc6638b; + aefc5f8584b7c5e617669c0f16e39815d4e9cfce + "" + 3e + "" + "" + 64f584488df21b4e6a7cb5b54551516ed0585564f2605551; + d1ecdf3d264a7f16cb16c2e815f422cdf0c8e303 + "" + "" + 08 + 93 + 9dd3171ccac6312ff23949e0145b1f20c157eb70c7a100cf; + be3c31e6bc58c0b7cadcb658b970e47479a684b5 + aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb + 70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0c + fa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456 + 2aa894b96eb2a06a0c601e1f32a5495741e7cd0d98ade2e22742931a96e86b1620f6bf3dc60e865f24029760aaac639a9628575a224c48cabb0b207a8c646da177f0180a9484003b + 09e91a6ca2951ac43b2dc376bfb2459f9d6793f3fa6f19b0; + f3ff669c732b58db8f48af65f7cc9e3fb90e1721 + b730374ffc9bc597f56ccbb2f294b38766fc69f6 + a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a125 + 8b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16 + 2a34e82df940e666655df615cd9499c3f0cbcb42d214c38a86130abd270c3f2a1aeb290e30d3aa4ff7e5386ebe20a7140c329e02f8e79ae908e55b44b32201191c1061d525d815983d8a413460155e66a4 + 62d2e5ef4662b6a369d06431d0b42ad0e89280500ba3eba1; + 687b7bb8deb9bd205b70e04c091d205cdad9e9a7 + 9b1abf91b0851e5ca605ac8451399587011677508a15dd + e524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd250141 + 07c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e + a5d9d4f2cfeaa5003728d73631498986caf5ecd07f21be526aaf0ba42f4e94ea4601b93fd94d3cba101bfd9f4092d31c37a787d481bcf6e0327ec520952a55bae4cfdff57b0b5aae071e182b89 + bff9d687d796f186e930b3d45a7ef9da7cb6309fece26936; + 6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe2 + "" + "" + "" + "" + 20e8e27fd32514b1b14272c20f0df7247f31f1f4a12f25fc; + 2d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94 + e6 + "" + "" + "" + ada7ffde4179f00a0efa887dc253ca41f00c318ed87aa2ee; + 6eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c + "" + 5f + "" + "" + 378e18a38eba655e06b6f1e4d453e0afbdecb51191f33822; + 87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214 + "" + "" + e9 + 7e + ab0bb740c0dc8e10d72db5f5d9340a7f3f58205422105151; + ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d96 + 45563a308ba60076817523bd2abf1261b089d8f23a9c2835 + 076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee11 + 9a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a43 + 3f01e886e13d4af838c1a081adb8940ef6f24dabe3bd968a1c256dd08fc8c2aef84f7c389d6049f553750678d40e05e73c272540a02ae22d37e3ea42b38b7b659661fda031256ac8 + 4e5447fbd4d6ae6b948968a3944daafb7dbfb2298afa517e; + a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab + 1eaadf66fd22ac1976063e113ab61f813e28a139 + 7a7974a1d7f4220c785fe426a5a0e80f678d404147842941feeffd + c2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf8556b7aa776945948d1b8834df219 + 0ce0e6e23e9b00a1925b4704d89f9ddc27e6184940419c3f4755b3a268f8ca0cefd898853791b75c9dfc09f72d8e3f1e76b68a7298131a24c15670b0f29150356b1dbb8281d2168fe870d5c2b13c7d515b + fc65f244ef465fab581fe151522e12881796968a24ec9f9c; + 6c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08c + e7cee4758a386a9943e97dedfbe61e737882cd09c2b9a8 + 0f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c + 3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330 + c9e1cff17ba016005ee6bd63700c2d80ed5281dd7ccd14d19514e1a0ec2a2134d9bef71d92a8bb3c71c0d4622800300d21d16cd076593c492361e2a849e71f7e51d9d6fff53b61bba0e19fb25e + 44aa54e465e68d39194421556344aea25bdc16f0a24c0685; + c43f3df6c2b3fac7cbcf9652 + "" + "" + "" + "" + ae9a5d3998de53f84bca8beed16dac8064c3ea73d0c67765; + 3d4723f91801325eb8553236 + 65 + "" + "" + "" + f062371cf3f7082c2e21c136112bc6dd3eb3b455a5624800; + 1c96788d73d192ee53b3f3eb + "" + d6 + "" + "" + 05013633667c00adb73c6442909065b53d12eb94db18480c; + 6ddd98cedbe88e245de25b15 + "" + "" + 93 + c6 + 78adfa0aabbe6558983554b3e73782cadcf950c21f27ee67; + b70f8601562d90a9b59ed034 + a867642d25d54756fa5c47f16f64b837bb4926214211a1c6 + 96ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed + 6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae64825 + da005542936f792bc7fed255ba5d8c04b90fa64185338a24a954b79a7d05252230a1167ef6eb35d1281c1927ffab7b5c714321e03a01274c3bd3583e3ec84f7c56d60000e18242f7 + 2ed230cfba9714d0d3d35df936ec750a695fccd25539b46b; + ecd75a66d88eedb969ffe076 + 69845ebb7a24c69f13d099f47166edf54538e88f + bf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da0 + 5780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb84241986c251f5b70be2367f04 + 85ed87687fca97cdf0ccfe1d4e0fbdd56e674a6ef5ebcbc4979f80e6f8ebdc85672d01db63bef05103c1327baa49d7e6e12854ce3680f52bde86c075ff5df02daf0db3e48b564a804cb3b657f982a27ff3 + e37d522450d16ff30f15ffa74a0b894bfd33074c4ea06f44; + 7265264e0da72efe8995e6c9 + 32a17eab511eddb8e4ba463c663035a6ae8a7a899e4279 + d54d03f0e0f3e961dcfd40088d5be74088e4097efb0368c7e2f431ee6988cf2a0e9ebeb3de79c4f86c9e4fba61339d6d907eab7707ca48ff5ba1ae93d16225d469de57 + 47bc1addf5748729720a320fe14fd29cfc59314fe2079c0a2535ded56112d6e3d33dcf7c71cd7d130323794e3da84a9df69703a9caf02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd1 + 0b9e340c141493f9676c99eaa36b0463639b3db40dce5e2bb48c3222a1b82595be0ae12890f61bdc22f71a07b8ad0136d395221c57e12ca7f8184d3adbf82497f5c6ac105b1545d433a9baf50f + b24035d9900bc75dc879617502f0f9891a2428fa9d6d472d; +} + +rijndael192-ocb1 { + 60d7bcda163547d348b7551195e77022 + 907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268 + "" + "" + "" + 13b24e23a3819cb4d7bf3ca036241de7b3420a061b6d62d3; + eeee533285a6ed810c9b689daaa9060d + 2d4b6003062365b0a54364c76c160f11896c4794846ecfa1 + 4a + "" + "" + cdea5e7be1867fe4017045e85df90d80eab16117019cb8d6; + 7130c9f137120634c9519848a877ff77 + bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba + "" + 23 + 82 + b32646848740cec0d5c5a20e2d56c34d455d9574159fc509; + 4085406a6136512061f7080cc07df059 + 1d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c926 + "" + 9029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b00 + 5f7a353fa6c23af6ae6afcd8fae5637d8ac4edb01faa216d94a8b31628140de88e741c1acd085a5e98d64f69090556f641d8f1c813fb1b3675a35aad57f6f48ebb0b7a8270df4216 + 76df452b066d18894a564d78abd6d0c649602bc325f73595; + 0961040ef2f9b2fc5fa450727a9b542c + de52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a + 97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600 + 157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa91563 + 6ed78c4004e5960f34017f9272ef3f237d5fd83076668683183dbc0b62201d1223550af95841dc4ac72f0bc0ce36f014237d026518a6b1bd0ce01e56e87bfa9c42f4651365f65b8c + dbfa943531e52ab36828c47f5e21fb22ea0452f0a45395ac; + 08cdec3f768281e040a9b9a222bd689a + ef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233b + "" + fa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff + 74751fe7898b6a9c7e28c4e3132fccaf4b9af8ceb80ceebc88672c05c49d5286724ddc6bd3dee79921cdf0a0265277d43048c588e5d707488d1dfd90808d6b74337d1e88aac9618ddf181c1653 + dd9c6625bb9d22266087655b51efc0a2d8cb642f6c40c6d7; + 3bcd211499268878dbf30f1dad89d4b9 + b12012e4713df46795630e7952d22bb02d7100b8b649377d + 20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ec + df3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b + bfecbe5ee869f7c5b4bcc3282963ed6dae5755c25a070c40b4d6a8dfb74670bc440d0af7abc018642d36a946d8488aaab9eabc0c7cf4ec6d2f8a9a738c131188af47d7e791c3f7e6a34d26724d + 5dfee1b1d0a1ebd94737ef267a755fddd2092bfd35e7a238; + 6d00f06dc188d472a784e0c6f21195a3b9f4ae98 + 5511265febd11c164720eef9eb1c8dd0b00951f284649016 + "" + "" + "" + 6c1ae06b473969bf8d4abf8890f91ccba11f094b316d82cf; + ed00456331854bc78bf43966eb0cfa9138ddc399 + 08445608fe95e81c2533e31c9c1a9851bc2810d858cbbc84 + 24 + "" + "" + 7025cfe14177506ac341239746234c80533c6fac1b94afd8; + d126b807e6daa089c3f9099c5ffb824173d7634c + 04226f30cbb7f0e4a973a8cd190107314717a77456f3ff66 + "" + 9c + f2 + 91c9a9506104ca20249008a5210a18e972aa0865d8c083c7; + 732b58db8f48af65f7cc9e3fb90e1721b730374f + fc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd5050 + "" + 03cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3 + 5c8a44ab82a0c2efc66e6e039e7c70a611991b5901b7578c55f4716fb7bd37f55c4bdc962f7f1ed93e14804b4d41695d639b3b5b1725c9129a47ae9542d11787064051cffca20611 + acb050737b017b0b4c10a120a4d740a2ef33d5e26e7251bf; + a4c84cef64f6c9b53bf8f957f4b03cf43e89957f + 9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205c + dad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc + 338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70 + 77b5382bf3a2e0f3545f398ec08d94825572da0ec6bee8d16a98d42f246eaaa8d049499dcbb872e5d751e700b3d2edff7264c1eaf2f0a0c8987932a53e171e62c2364212f3ef3405 + 87c558d944a7c325965931188213f6a37719581ade0d0561; + d17d4569eaff59a332ba58d5d5589bfe079753ee + 1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6 + "" + dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de128 + 0f50a0d3b7e41c19a9ed4c679ae42b4ba5055d3e9c60652c07daa390cea5c499787ffd7dbb1cdcfe095ac7549db82c3068e053bb2fe3fd8a5749d653be84a5ffadbc1dcfa6a400006f6badaa62 + 14270e56d692e540aa7cb92b1b285eaf00c6e183c6f03341; + 8c69d80ea12ff4bb5f069b8a2e86041c1b9fc214 + e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa + 6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33 + 958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1a + d9933fb77ae951691f9b11b7eb9a949191c1a39d09e4bc78a0be75bc8c101ad281eff87a1f5da724d79235e949a589b39125d0a91025a9e126054d980307b934a590687c64e457991a88895367 + 03e5dddeb49ab69f6a062242f8c1a0d1d2efb55895e03a83; + c273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae475f6b94a + 43a67b3d380d2f9aaafe2dd721c0095c8808847689211450 + "" + "" + "" + ccc44a234758478dbf8787d423d646f61b0cda1598fca3bc; + ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974 + a1d7f4220c785fe426a5a0e80f678d404147842941feeffd + c2 + "" + "" + 49e97ec66094c4bc5ab035aeaf6cc43dacae0f582021e584; + eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e51506 + 86d2301b43a15a84e81d7f5cedaa49e2414ebf47970e5604 + "" + 75 + 48 + 8128cb7db1a943e0cca309d9204164fbd9c34ca6c07f784c; + cff206877de69146acc3ab6cf8556b7aa776945948d1b8834df2196c + 92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07a + "" + e8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b0739 + f8e281d776b2fe8726809be7abdd62c22c4b523b7613a5858be2a07021ed3dee1945f62bb37cc0be1de3b1e475ed5828ba13a26f34e2651da980ca02602c5e58c8834ba9e8cb5e5d + 97fb24449e5402189c30187aedf9627577f0397158331735; + 8a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef616 + 14c270295dfc0ca6551ca4bdb75359f91cb9d921056b7de7 + 4fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c + 96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22 + bcfa139e6fdf6e5bcf96a5c29f8e0145c1d613edd25b9653bf6772d21bc6ae69fa71eae2029716605cf398247b7f2e5a97c5886d94fd674c40b5d42218c2adc7f84770e7288fab36 + c92aa7646695a597df47a2c686ba2abe2b0d20caa4052185; + d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b + 1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839e + "" + a59cc783443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8b + 2cc3069cc00db4c51fb54ccb6ed44217a5169eeba4d3fae16878af2b0f969d5ed42da3fe8901645369768e0ca33cdec8cd422a0442c798d8a214fdbec4564b09d70666884ced9a0e64bc9eb3d5 + d9a32a67db1fefa016cd7961df3e0a9e9949168242a2181a; + fae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f4 + 7166edf54538e88fbf433a7ff212085179e79771f6eee728 + 3ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c738f4cb0f58a1e3 + 4c8b15ad930c1b627235a2cb84241986c251f5b70be2367f047265264e0da72efe8995e6c932a17eab511eddb8e4ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd40088d5be74088 + c077af8264ca4bd0902dfe7c6f43dc4232c619bae8d151f9be98caf39527e373efec0dc9fa55b62f207b533724b78935255a608e9ac32da258e8f4549d473b95b9057900b2f715425d19804801 + 125a60f3f7f0913f203632d93f4f2cc70e76ca59cfda9a57; + e4097efb0368c7e2f431ee69 + 88cf2a0e9ebeb3de79c4f86c9e4fba61339d6d907eab7707 + "" + "" + "" + d040e427a7ea51019b49c65a9c38a803bdffe3635357b8e3; + ca48ff5ba1ae93d16225d469 + de5747bc1addf5748729720a320fe14fd29cfc59314fe207 + 9c + "" + "" + 2bd8090e45ccb18c92e3c133a19e0a3d3bca6dcdc4f5d591; + 0a2535ded56112d6e3d33dcf + 7c71cd7d130323794e3da84a9df69703a9caf02d2a8f57ac + "" + 71 + fb + bdb4cda8932cacfa59b5e1635a394ffae6a03ba034759e86; + e554a6850d55882f8c7ae699 + 4fc8528bd18c374fc43581d2f72a89584a2404a059f7f99c + "" + 7241a0c879d6d4455b382a9ce757b3e7a1d07585ad9d7ea9c7c9cf54f3bc6d94238ab56d738e02abd651477cd726d6f3ebcd6fadeab50906642a7de6496247060e7be3632ed9bd94 + b29f37bc84835d3cead667fda5bcaef6a0b93a0e1e79169f94d0111d28e0374fe7cc4a2f9ac274c3f31121d2a1058094b6ac1707f92c87a45301cc2451eebd8501d63a8f561d2f86 + 40f807380b82f25a620597ef741e74638ccb5a7a58e4bad4; + bb42f45a8733b2cd2df9d1d9 + 05cfdb29983050d6bcdb686a0c897031ad09a5b8fa687ec3 + bad8e18dc2ad361f1e226e78876cd35f86c639733c5cd84aed8aaebabb7e0f24edfd9710b7bca91b612ea37fc5cc09f7f62f66b423fcd2dec5de24d264f2c839839c1b06319f687d + bc68d9f07fd41ccb4f8cde8de201ec2680332bbded4883deea0b58b54bdd13c17ef292b0ded3caeb5e57fd21df10bc6186265ee6ea45907de6cb822fb2ef953aea358a03e0fce2e1 + d3445b37b2ee6f261baf94fd09ba0121b1ef9a8dacddacff5ed3bf46c36cfd1f2a5e9a1e35b73299bd31137a2a7746c8b46eeda7fec1662842934d0d1b41d240a40886e17f3733d1 + 2f65d5e606ea39bd566246b137733278aa2942ace8edc2fb; + b9511bd332c86e67f123377a + 8f0256b8dcc73ae1b3c6cd3f104e3cb24284cfed17811d64 + "" + d492d39ea7496993a25b072945d83f923e66b0a6689cf0969c003a8fca80e322a4b1bf050c1220450433efb6b6d8a2d820cf27a64b9d47f636845dac557bb3e75f3a18fb8e173416867fcd0ee7 + 65bb74fac682e5422c376f255b91a383334486c836f5f5d578b276ef240206a1761e2dc66109d2b11c4b2d25411c5e0a86316501a1a22a779ed2be816b7b84ebbf1c0cbb41a332dcc43a8d0912 + 0023df18856b33924dbab9d86440a7fd289d314aa17a282c; + 8ddd9236beec76d55ed58b10 + f91d07a037791ab96e83c4bf2fb5b205e592c172a5cbc194 + 56c95c1bea6079f3867e52d663cb3884b2a0a8ff825df752423f3179bfeb89eca385f20ddce5f1f23564672e370ffc37d400a31e8aac1d426ce10df73c5ee478b3b63d + 91024780e974a8a2a0e7a36f84ab1286b627e7d01b38a84a6de738721ed80fd0d7f69fa658abb5a440d304128719b541a9451cead18e4c61d93d1f8fcc53574427767396322b3bf7d02cec0509 + b58b1c9dc465be8b7159c9f7c4b8ce39c251d39792eda3da5be8ef7b887114bc1b5af143be79983b37a11a0d96082c924d0308999a39734d0d6eee63e651be9a2cb1cb2fc8aa6db22bb146ee53 + 210b175366af46c07715847dfd494cbad171f2d8ea711f9c; +} + +rijndael192-pmac1 { + 60d7bcda163547d348b7551195e77022 + "" + a2de3f1a78f51e79b270024ef181a3c7866c4901882d8f2b; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + a69a6414d3476b1fe006cd01597794cdd6f335aa776941db; + 8f86edd1dc9268eeee533285a6ed810c + 9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba + 8cadcc0f2b6f103713f1875836da1fec0d2492e592969018; + 234085406a6136512061f7080cc07df0 + 591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49 + 5fb116908156463f1b1f698e9cecf1e6ba99c5292359e8ce; + ae1d50c38201a894476b3f102b752eb952953396 + "" + 9590db354fa1be8edc4f4464d0e292ddc6c38614cd7a8d9f; + 6f27043eb621b7f65b000961040ef2f9b2fc5fa4 + 50 + d4354854bd0f842a2d7d2d1ba28362a1ceea024ee706eb41; + 727a9b542cde52ebfda19d0ccc520f215eb57bb3 + a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f + 979f0fbf31f2afcafed5d59414bbbc8629c5c1451ca52f3b; + 8f28523c03d4de1600157846b710ee72807a2219 + bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f7682 + 9b980aca9bdbb8333cacfd8a76c8bd57e1862136831e194a; + 81e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a + "" + 2e46bc43892089f8eba2108812c2cc5c4ec74ae390223bac; + 42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c + 03 + e7cf293a42d599e87773781f8abd4a303f2967de3a36b17b; + 7ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9 + aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b + c190a80eb16dea538d732bad5c1d06decbc09ee1a4eee891; + 663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef3 + 15d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e4 + 54fde6333577613aebc01d5de58556aec8dc6911983a136f; + 7479a684b5aefa69a4cd5214 + "" + 1d0a9120f17311d23b4babcdb18d1225ec90fa3276f35054; + 7ed12ca986981a874498ad0a + be + 34750cd4fc57273de4b5858c39bf05da2b0156496adec2b3; + f8bc4fcb70e27e98ef1f0446 + b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc3990844 + 22e6ac9f6fa50e49f0e24e710d62c83fdb6ade50f102bc31; + 5608fe95e81c2533e31c9c1a + 9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e + d3653df2ff5ca70439d6f154551ba9ff27c5ead8db7af2a9; +} + +rijndael192-ocb3 { + 60d7bcda163547d348b7551195e77022 + 907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc + "" + "" + "" + b5d14574dad19385409d38eddbeb6afe08cbc6e40260f7c4; + 9268eeee533285a6ed810c9b689daaa9 + 060d2d4b6003062365b0a54364c76c160f11896c4794 + 84 + "" + "" + ff39389f60d0cb58841212408f59c1313e57029630808bbb; + 6ecfa14a7130c9f137120634c9519848 + a877ff77bf79192a5b50ade5d9cd739a3d1f337f2954 + "" + 9e + bc + af0809f4d9e7b23e1b98f8b65fd7326aa8b546065218757e; + 6b0d27a4ba234085406a6136512061f7 + 080cc07df0591d8fa21f2dd88374d8cde8e160 + "" + ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533 + 0fd527536eda95bc7b5e1e67c5737626da7251fb0bb540e3a684656d29c7ee45e19d670d8c7a8a896633608aedb539b5e42d5d9d8d05320777dac9687207f733f137f64a36940ffc + e8df4fd3fac5b4b10a2242cc5ddf436f8acac68e0700dffb; + 966f27043eb621b7f65b000961040ef2 + f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f + 215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b9458630 + 6fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b + 715f3c2b119bc11bd4723df66915752c925e89e5652090168877845f6a5cf40c032b3a54887cf0cbae47edd7623c876a2e3c2035d0dacd42a8820bbd7a20d4991b3c8a98ad7d8331 + 1b8c5703782c163b28509cb1cb67e2e0bdaf949867dc63d4; + 0467cb9fc2712a199e533fa9156308cd + ec3f768281e040a9b9a222bd689aef66f5306ceb0c6b + "" + 08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063 + fe808b32e6844a1ae334b145183e092c6c18eec5268104868889f5e9f197a831ebea245adb9ead21c16461918a5b48f33720884758d98a55380fb9c088c60a120402a336a646f2499d44e59e44 + 455d8abc815b66b77c0c7b048215508a1420d501c6caffb3; + c46f88de9fd41e72d7b97e23e6eabdff + 3bcd211499268878dbf30f1dad89d4b9b12012e4713d + f46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584 + b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abe + 1c8d47ef199e6fb28c25a07ae8051b0785c73579e224b9e85990c66628a3e2a1f21e26735a47c3df4563c23c0e2814fa708566948113cca1fddecf2109c56dacd260689b45c72cedc522b593c8 + 652c3473b278ac660297c275b0a7beb9501c0d8654310b3f; + f8bc4fcb70e27e98ef1f0446b42fb144d44b6d00 + f06dc188d472a784e0c6f21195a3b9f4ae985511265f + "" + "" + "" + b0b54530145be3e9ba77f97799d7a386747f260b20c71d4c; + ebd11c164720eef9eb1c8dd0b00951f284649016 + ed00456331854bc78bf43966eb0cfa9138ddc3990844 + 56 + "" + "" + a7544f3687f32006a57591900a0a73224133ccea2e6c705d; + 08fe95e81c2533e31c9c1a9851bc2810d858cbbc + 8424d126b807e6daa089c3f9099c5ffb824173d7634c + "" + 04 + 7e + 13f61abd0de5586dc8a054920b885d81a075db59807b3de0; + 226f30cbb7f0e4a973a8cd190107314717a77456 + f3ff669c732b58db8f48af65f7cc9e3fb90e17 + "" + 21b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554ac + f67230d596aba65ecb5d1708bf3eea0c2b8adf346fdb033f4c6dbc9e1b1a394353d4d054ceecf6cc9fd93487da8a5c70feadd5067c9b20dd5096418c2b1d96de1c24ffd51d6c376f + 4e72953575d116de1f5283af168f6c9e93abd250d36e966c; + f1270485b203a3c1c4c967c0a458cb948bdd409b + 687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957 + f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ec + ccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d98351 + ee2b2fc312e954332969db113f066c2ca26a2a521308ed891cae549afdc3198d1c1e154c73a675cc74e893c95a0e52473ffc15b5540339b3b3a5e62bd36be0e08c5d313d2a1e8cf1 + a7001eb1a36d838c1425c07ba29c9f8914094e5cad71bbf4; + 4605ec590294a319b9802068a9f891bc5ba5afab + f8c3122d12d7ff3c41122d70d17d4569eaff59a332ba + "" + 58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb456 + 1411b2dc14e6fa752fa2092a36657ebf4e742ad3f74267c6804dd6e9b508c526639d7ade46a49af597966bd5c4cb83ca831f638214498d700b7b52512e7d1fdb1e2e4443d5f2e110901730461c + eee75d53b2357e78a5b5aaea134f60f48bcc4a6d0f5c8998; + 3d405e51881e99027b8ab9aea3ccf860b0009740 + 763d96836c5f87b95460938de1288c69d80ea12ff4bb + 5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a + 23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2 + c4a9eeb3f04799ce6944e8104509fa1aef8f17b5815ba391c356d895d7cf996513eed08a74f58e01e534f0f5c3079c770e255a9278fbe8a3da967a01d5536b1a87292db733862f4f98304a7307 + 0dbf831632cb781a3ec5c78d99e363ff3e7dfa646fd9e90c; + b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a + 92142b5b0677da1ac273117b45bcfff5d5f8b6fde289 + "" + "" + "" + ed4dee5d2f4f878178ede9ff462515501765dd09987f4957; + 3232a9f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0 + 095c8808847689211450ba8095ffab1eaadf66fd22ac + 19 + "" + "" + 2157ffb54f20ad64b0ae17d72c99dcc7f14093b49121bb30; + 76063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f + 678d404147842941feeffdc2eb44dc8c0d5e8f444f7f + "" + 4e + b8 + 0f3e95269af57fd63b09cac38f5c5f0934a752201dff056b; + 0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f + 5cedaa49e2414ebf47970e560475cff206877d + "" + e69146acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9 + 60b0cded984a7111026de06190745d65af6942a64b7561ae21f68d213ad0ad22ac6fe56c8b7dd756cd9bf6ba13c2c011cd99387ebae0422a4e12e11ceafb0292de2097a876e5c416 + b28761e6f95f1faef3e4203ed6bc359c0406982b19d8a6d0; + a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9 + ad5b04140d98edabe08485290a4d87d13b07398a14 + 58c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7 + cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de2 + 76214c8de16aa91bb77876d7975b49cc15da1a63487133994bda609099c60d7f0d2bbb2efd5af7dc3a276a56220004edc7b1da45c6164d91d77772ed91d587b9caadd20e27d078db + 38e894b028899b17056bc987b2ba8fbd7cd6d0cc4a50fb38; + 5b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f + 64b837bb4926214211a1c696ba172010abb433922a22 + "" + d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca34fd6544bcf86b799e + c84c85f543c7f56134b2b5e0a48c384ee52d231d0706b2524d39cad86d4e02c085d3c95f96e0e4bb5189376b5276d0a7bdf6b554d92c8984168596abebea609707fad78cd0ebfd0968823854f2 + 04a3929311c62ac5a52e41328632178462d078e4a495a115; + 2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f93 + 8f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c9 + 4b8bfae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780 + ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb84241986c251f5b70be236 + 7f46b1b9de6077c8ec8d7a07c53c4efe4a7fc60cb8de683164df9faf4b4bd540b6076f4f8449f215ebcb17f73ad9d2d92930e0134be8a56fca74f0f945100425438085e7b3994752a100db09d7 + 8465609210664b702ba7297e945027461069d9dab09c8ada; + 7f047265264e0da72efe8995 + e6c932a17eab511eddb8e4ba463c663035a6ae8a7a89 + "" + "" + "" + 867ef0e4e4136a82e85c2ac3a7d6caa7a0c4789af22df032; + 9e4279d54d03f0e0f3e961dc + fd40088d5be74088e4097efb0368c7e2f431ee6988cf + 2a + "" + "" + 9d88b7a1abb6dbaa577fb9032334094d426045ac2b848598; + 0e9ebeb3de79c4f86c9e4fba + 61339d6d907eab7707ca48ff5ba1ae93d16225d469de + "" + 57 + eb + af67bb55608d1620c17ca5404cd788d4eb6c738d9597fd13; + 47bc1addf5748729720a320f + e14fd29cfc59314fe2079c0a2535ded56112d6 + "" + e3d33dcf7c71cd7d130323794e3da84a9df69703a9caf02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd18c374fc43581d2f72a89584a2404a059f7f99c7241a0c879d6d4 + d72178266c9c112c4618e31aa17d1b48ccb51963204539bb07ef387a95454f43c4131e65c1fc4cc28ce70666995d4c86b69f4031edd9abe6e71b27270d75e6c786282401e38bcce4 + a9b01accbdfccd6b65c684d04a9c836de6b7377c93f066b4; + 455b382a9ce757b3e7a1d075 + 85ad9d7ea9c7c9cf54f3bc6d94238ab56d738e02ab + d651477cd726d6f3ebcd6fadeab50906642a7de6496247060e7be3632ed9bd94bb42f45a8733b2cd2df9d1d905cfdb29983050d6bcdb686a0c897031ad09a5b8fa687ec3bad8e18d + c2ad361f1e226e78876cd35f86c639733c5cd84aed8aaebabb7e0f24edfd9710b7bca91b612ea37fc5cc09f7f62f66b423fcd2dec5de24d264f2c839839c1b06319f687dbc68d9f0 + 598a1235709ceae2308d4c08c0bb6019a8797608d983e6701893d983b7574662a7790da0d68b07299907272fe218cbd19549cc10b1aee2f70c23b1825f734c222369929d78780ed8 + f8998bcc33440204eb8abe0ae0a50dfc6d59eac76ea51cf6; + 7fd41ccb4f8cde8de201ec26 + 80332bbded4883deea0b58b54bdd13c17ef292b0ded3 + "" + caeb5e57fd21df10bc6186265ee6ea45907de6cb822fb2ef953aea358a03e0fce2e1b9511bd332c86e67f123377a8f0256b8dcc73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea74969 + d66d4a577c1df9ddc37036d5ba8206a6ae9b59bd7d9f096c4184be067aa8c6f836251fd1187edeca358a375cad0bd2ab89563978941870552c94faf821971f77c1583e51fd5077f32b9b5bfd0f + 1f839690aead572ae9fd15ee968983dd34fb8dbd4e5827be; + 93a25b072945d83f923e66b0 + a6689cf0969c003a8fca80e322a4b1bf050c12204504 + 33efb6b6d8a2d820cf27a64b9d47f636845dac557bb3e75f3a18fb8e173416867fcd0ee78ddd9236beec76d55ed58b10f91d07a037791ab96e83c4bf2fb5b205e592c1 + 72a5cbc19456c95c1bea6079f3867e52d663cb3884b2a0a8ff825df752423f3179bfeb89eca385f20ddce5f1f23564672e370ffc37d400a31e8aac1d426ce10df73c5ee478b3b63d91024780e9 + 5ccb483f688309a92fdd49b62e82cd6eba809cc87085e08037d2ec45b51db4dee112b3733a650f1ef167d684e5fa46e62ebd7002433c0022874a5839bc57b13f41ac3d221d0ec3d6f727fd1a8f + ab66a6b01196d8dd216791da419b5cf132788abed4254d85; +} + +rijndael192-ocb3-mct { + 32 9f02c63dd249efeb7f4d8453ee3c38cfc9930a7ef42faf68; + 28 abd57fc930c095eec2d8cc466a26ed96ee9b4ce00bc02b32; + 24 ff3b3dd8e0f774136f01351375c53605687c0626f0456253; + 20 c05ef316f4452a992aebedc3565760cd61dbc635db5b01b2; + 16 3e89734e70fa99dbe1571178aa1edb917330932a2ff6ac64; + 12 7506243a5da5b0cfccec7138bdd6139fe41407bbb5b410e1; + 8 e6aad44d2d891651052c6b1386bb10b5fb782976df1c1e70; + 4 6ddb5a25933d8061b4e5e77ec3cd10680308a5dcad517385; + 32 906dddd0884c542b133dff61c61f2162e9d95b10; + 28 33d3e253c75e411ceeee00c9a0210f7c712ecd66; + 24 859cbce898522f5b8722d39fd102288559711820; + 20 1d323ad20a20660b568279370228800d724d4c64; + 16 7604277e9535634d8a43f77a051914760fba923f; + 12 a144bd8fac2616e541c222cb1d8fa1937901dff8; + 8 9e4c1fb5aabf111ecb49545a92dc91449345ec77; + 4 b2a77eed505ca3ba5edc1a95cac166b02f7ca515; + 32 52b3de9c9a0e7a7f3f65170a59a0a959; + 28 925abc1d13cf9aa5c0fbcf73ac78b559; + 24 08db50d58b2e97c2931e231775fbabae; + 20 1c154b77e569e62ff13603a6397bf88b; + 16 a514526ab5a5f5622632bf8dbb009f74; + 12 1b483b245d9c11c1ad947a74f7303b27; + 8 ec31ba263ee64ec9f0e4ff4d7a2498f3; + 4 dcaee7b3276238b3d9c946ea970d823c; + 32 f43eb7ac65b4f6cc7ef4c1ef; + 28 ffdeff14896db787f8b9a8cc; + 24 e3d0eec8426fb7223622eed6; + 20 7b9b29ffe3f2de6b85b2f542; + 16 4a5928e2406cf876486539d6; + 12 e1a51d35431662bd48c8d4be; + 8 3fcc5d9987661e00bbe41201; + 4 c5a4cebe92b555fe8a3bdad7; + 32 dce58465343f136e; + 28 6ce50ed44f5d41f1; + 24 876ecff3404f371b; + 20 605b7adeef15c3f8; + 16 a56e57ee9e8f5130; + 12 48ebd3b98cbda23c; + 8 c34363871760230a; + 4 484de0d92485471c; +} diff --git a/symm/t/rijndael256 b/symm/t/rijndael256 index 732685f3..803b2d6c 100644 --- a/symm/t/rijndael256 +++ b/symm/t/rijndael256 @@ -2895,3 +2895,931 @@ rijndael256 { 1188d6578860ceb90a80228c344c3d9e72e775cae5d41b0fd9ff9c60d0898fd0 ec81f1cda5409281c7b4d5f698b6ca5d0ec79598571237a08a60a4a0724b739a; } + +rijndael256-cmac { + 60d7bcda163547d348b7551195e77022 + "" + a45b5e26bf4b809a89993f34d7b96a1518383ae7a57b51c1ac78cb29a1432a2a; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + 768cdb787a4de07dc2c7ff3c1846d2fbcd1bcf867dbe9f25607cca4443ee25b9; + 8f86edd1dc9268eeee533285a6ed810c + 9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd883 + 00c1e6af11c6d84eda40876c32f4467f45a0f9cbf862545bf05487fd06713dad; + 74d8cde8e160ad10997a21635c6d62c9 + 269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52 + 8f1442e79bfd604a4400d183e4509b454411b03d63dfbae7db2b03c998db8724; + ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6 + "" + 66129452d7b724416120de9f272b2d531a1cc0faaf945ab3160734ae639483f0; + c95a97a48030370c33d090c54215abd6b3ad54ef + c9 + 1576f9e568d9bcb014a679b7024aae490080ba401d8808cd9e2b7fe57f0eab66; + a38378c5b93bf4f2aad2605faee2b03fb648e27f + ff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2 + e2ebc3f8e727de99c6fd46bef8e7df52599e0f8de53567bdfbfd2b52b907e7ff; + 712a199e533fa9156308cdec3f768281e040a9b9 + a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c4 + afc6c9c54cbe70a0e7fa6146a5ed4ae9ce68a1d609af79708281be0c2715c8fe; + 6f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad + "" + 39733f351c3e4a5b686ff0a932407c4dc2f41bb387592881b3f92f915ece1cd0; + 89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20 + a8 + b6caa7f9735ae9ea8083faa068dc284cd5d14332984ced7f46d3e93bddd7fac6; + f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f + 1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abe + 7fcf4a19556a8ba23df01de57087481a425410f3f092e4f801a681625b713935; + f8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784 + e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c + 6377ee34258253260374a4654c8bd727bdef4e5921e59a770a8a6178bc61620f; + 5ffb824173d7634c04226f30 + "" + 4ad4651e26e46ac9b3890fc7adae23cbfcf808d96586a4c88a27c6a8533b51c3; + cbb7f0e4a973a8cd19010731 + 47 + 18566621f2c24c55bd880e8603461de80fcf01ceeda7bb7aedb4253204372e14; + 17a77456f3ff669c732b58db + 8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a4 + 16a524c850d351e451cd482587f4f622542283b085e16ba423c8c54085b08350; + 58cb948bdd409b687fa3a682 + 7b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d + 3e8977f205b75e6fae2105cbb8cdb26f3e8057957ce69b9e6be62362bd225924; +} + +rijndael256-ccm { + 60d7bcda163547d348b7551195e77022 + 907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee53 + "" + "" + "" + 39e9b611; + 3285a6ed810c9b689daaa9060d2d4b60 + 03062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137 + 12 + "" + "" + 2de43d0d; + 0634c9519848a877ff77bf79192a5b50 + ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a61365120 + "" + 61 + af + 8b7456f9; + f7080cc07df0591d8fa21f2dd88374d8 + cde8e160ad10997a21635c6d62c9269029 + df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f + 215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a22 + 87e66fdcee4d517cac9c5df8c9a1250f9b4c4661766cc1f92ac99e539d615f16e9e922ed9a2858ec999c25a625c576360c99583babc0f0a2730dae7a28d505f72933cac1614ff406b2e57a81e42f6d939201ce863d146cea017de5759a440f99 + c225cb11adf2da0fe435a56b3c32692e9b469cd9a3d596e980fd06753fae46e6; + 19bfb474fd71d891f24bb65d1563259f + 9eb53b571ea629c54d57dd2d42f70800df + 9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c + 037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b + c16a37dd487a042d5ef9f8e37dd62300e0f990b5d8b4475610726cc6c1f459079618a0e57a0c1a7edac73d37fc0b34772afc4db80db4b0955fcbe20cec2f09396f6b6935df5ba6a663eeda17386b5c2415a5ceba8da9f024d7ed0375d172cb64539a55c133 + 997e534457f57e31ac0bac767af4763e3289abe713dbe1b044dcd9d06e587077; + 663e4ee1315f3c8f2aebfa921451dcd1af5813b7 + 0d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617 + "" + "" + "" + c17f8532; + 669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16 + cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970 + e4 + "" + "" + 9238fb01; + 7479a684b5aefa69a4cd52147ed12ca986981a87 + 4498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06d + "" + c1 + 55 + a72c2d2c; + 88d472a784e0c6f21195a3b9f4ae985511265feb + d11c164720eef9eb1c8dd0b00951f28464 + 9016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db + 8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a4 + 58aa01bd9e621d51a56834475abe47e312b92c5cbc9ba2bda0b6c93f8205dd034dc7ea07fff025df7357c96de86f1abb81b7acd50c8152c2cc0b858a1a2269ef527b5b29b58b365e85e6a0c86c38f84484dbdb52451e8b9f3045b87d027d4274 + b0c5980dd1d865f66cf8afcab40eef4768d8eae4e3df3af89474ba26805dc97f; + 58cb948bdd409b687fa3a6827b480aa3a4c84cef + 64f6c9b53bf8f957f4b03cf43e89957f9a + 3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90b + bf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6 + d60e61dc2da592c48e916f6185dc2f21f8f81967a0606a90d65d2cd698eb7a496483fd545a49496f140faa6f9faa01ba37877b389f62827032b6f212f454415fe8b55511cbe76dd33304342e41def358962982d37f447e45ebdf80e1da9e971926bb261b8f + 2d6f1893de28ec8fe81d627c746bef1734bdbf70342adf8366fd9ee123893f8b; + 699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90 + cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d9803 + "" + "" + "" + d5c932ed; + 98bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b000974076 + 3d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86 + 04 + "" + "" + cc3630f9; + 1c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ff + aa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a + "" + 9c + a9 + 893c9eb6; + 2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a0614 + 8f302c3973accd56f6f24e33958b8c2e23 + 52fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517ffae4 + 75f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959 + 696865f6691e1d423ef29c34769d153e154cf60958dca4671f95cd3e798b078ac5bb61ac610a204ae8fa705e0049e67e33524939589b79f2dd0a4afb1af3de3be22f63024fbeb4114fe9d63599cbb6bbeb46b6dfbff4c4c4045a195a9f6e841f + 2f8b9f3db32f5ac54b01d587c12a62439f1c211ae0d95749c8c6307a53f94832; + b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49 + e2414ebf47970e560475cff206877de691 + 46acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e + 0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb + a6c5eba6167038a4cad7ba1d4b56486454220bbb137441c9dce2aeaeff28d7483ed42af4e09ada32dd9378f098f84a1490feb1b69fde424336de7ee13cf3d78e98b06d4c256ea7b2c8d09a844183d4fbd9ab8cb1e5daaa68065c654f913cf993f24352ea79 + d12d64dd43380368b4c96be31ed6506d5062d06db2b9feddd8eeaab6e1e05328; + 23841da1ae8f4ae480cda98a + d6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cbcf96523d4723f9 + "" + "" + "" + acf8fba1; + 1801325eb8553236651c9678 + 8d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601 + 56 + "" + "" + 3ed65cbc; + 2d90a9b59ed034a867642d25 + d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb433 + "" + 92 + e3 + 1e19bf8c; + 2a22d9fd881519165eb9d851 + 97a21cc34ac0d5ae7be8dbf98e4ffed2cf + 6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3d1d2e3 + 1e4e34c94b8bfae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e7 + 0a55d15edec4262afac43ca1fe8e3d9ef79463234eaa45795af83c017e36d9238ccb373eb40a3eac59f2759558e25e60769170f0f38a433a24587c8c525db9af75cb4a3e91f0dd7cc0d59599eeb07761a35ccfa9c548b681e2353c743f60a4e4 + 9995e65234d6516ca613e75bf36b740df93c28e99cf02c5b1b9ac12479373025; + 5079bb018ccc8c54f31b450e + 88f8e9002926ad0284c738f4cb0f58a1e3 + 4c8b15ad930c1b627235a2cb84241986c251f5b70be2367f047265264e0da72efe8995e6c932a17eab511eddb8e4ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd40088d5be74088e4097efb0368c7e2f431ee6988cf + 2a0e9ebeb3de79c4f86c9e4fba61339d6d907eab7707ca48ff5ba1ae93d16225d469de5747bc1addf5748729720a320fe14fd29cfc59314fe2079c0a2535ded56112d6e3d33dcf7c71cd7d130323794e3da84a9df69703a9caf02d2a8f57ac71e554a6850d + 69a364a10ea53ab96e931e5c449427a40d2d571e8beb2dbb7577edd3c581456358be681655e7490b139a138ba9ffcf95636344a6886ae4e222f46ea7e5e6e4529c75276734895d322770de34b9919b2e7add2bfab0952d053b8991f39198ad4c61391d691e + 77bab4bc3ed79b9a7d89be7f7a3f82f34628063596ce73129905c0020b9bc0ad; +} + +rijndael256-eax { + 60d7bcda163547d348b7551195e77022 + "" + "" + "" + "" + 56ae717b581681545bef99f97673b07d76c5f29cb1fbb3db8b99d59c99ab042b; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + "" + "" + "" + 1284871421d525f5fea4eab5cd3236ad719701f0ab7e0f5de835de37e89c8828; + 8f86edd1dc9268eeee533285a6ed810c + "" + 9b + "" + "" + de3475c1039364a38f98e4ec3c432edbe31bed2b4ae2c5bad8d3ba1ec6338ad7; + 689daaa9060d2d4b6003062365b0a543 + "" + "" + 64 + 8e + 9f58b74b0c8c4612ddd9fc1a0a2ade2f129882dee66e9c7943d55fe32cf0c7cc; + c76c160f11896c4794846ecfa14a7130 + c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f2954 + 9e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a8 + 94476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2 + a59e5bba670ccd7caaa3eeeb6f7e45093846a32546fa3523791b2f132404d9a86f0f35fe46232811cd5b654c9e275c6db7f79e530cde3ace91d7a637ac4cbde01e09560059afc2da7aba6c16c5dd412608263b33187e27bac08512b611bf3819 + 21088f614b6dc3f1ca5a6cc1dda35b59373dc77f9a4b91954ec75ab8ee1f3d4a; + b03fb648e27fff63102758fe2b69ac26 + afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee7280 + 7a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b + 0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f + 7e11239c076c83d990ba728f083f5e6937e80b81d31b1e8bfc4dd1341e4023a3b403fbdfc112b81795038ef923c300ed1c7a49399f873632ab1d48991e4484e3ed7ecbae505e69dea28e8bcb34d19a4c825d17ae6b3000d69c7729c66a4d75232e392573c4 + 37ccc36ae5a0cfb968bc686d6c61844a13d059ade69efb70bffcc7f4527e7db7; + 1dad89d4b9b12012e4713df46795630e7952d22b + "" + "" + "" + "" + 2a04e16b231801a616818eb325a3b6b4455ad7f0feb221fc9cf7ee7ae1f77975; + b02d7100b8b649377d20a8f083455b663e4ee131 + 5f + "" + "" + "" + c60fd57a9134b835c1a6ff8feb240db21bbba1f499562eda9487ba0046bcdadd; + 3c8f2aebfa921451dcd1af5813b70d30ce2f1fef + "" + 6e + "" + "" + 1c74926dd4c104bb6b4547117904d442e2f3a5f26fe303f2777d83043f70f6c6; + f315d0798391805da08da3aefc5f8584b7c5e617 + "" + "" + 66 + 4f + 4aeae19b9dcd25ad5b8bdfc749075ee42ad0352e7d335e6ef8c1b4d120eae1d2; + 9c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb + 16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5 + aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0c + fa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374f + 484516291ddd8425984d5b20f7951606f6992d02d8c39b044d86ebffbda479500671ec82f8c95889aae76eaf968a38aadba8c8ad820f319a72a6c3ca67d62df2fa069092c12337a22ca4be8438d851ee7ceb4cc6479af0a0cb8b5d6ab3a3c33c + 7fcc60c87daa5c131c20ef01161149e738b313743c0165fe272fffa6b8e04be1; + fc9bc597f56ccbb2f294b38766fc69f6a9f2c094 + 5ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d + 65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9 + e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add95 + 80366f86356bf3c47346f4ed75e7d21bdc49ccc63b9e606e3b322c53cc173537b7c43254b80bd6c044e2b778eddb8ec32d126c5cdf51c6e3bd13c5f48f8cf1e7596ee01b4ed1d5484ec4373aab252d08f61b8cb40c7ce46b561918f78ae0cdebe8159e900a + 8210e8551e214b45eb7e34f359022505753cf6a60dae9a31c4baf9d44abd7f87; + 89d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5af + "" + "" + "" + "" + fd2fb424608049e61223ddd23da663c101854f3787a5bf134ebc623070c80e88; + abf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589b + fe + "" + "" + "" + bd15c0ac8e80c6804cb853a059119ba0beec66a6935ffb590c4c6aa53abf9b89; + 079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6 + "" + dd + "" + "" + 8828d3a99b3ab60db2a397ddd9f0a0191aebe0e6a0d6f4020f3a281fc67765ec; + a7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44 + "" + "" + bb + a1 + 68445bb171a21e07feef9aad62a8069f645b621974ac7260589c4b5a5a309c3c; + c8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf8 + 60b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e + 86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f2 + 4e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9 + 8f3a1855096bbe241f41b1084e58348e129ae4256d8b73414c3bf9eef729acc2f8a5a6f74ed553bc315b0817f0ab372ac20a58c13dd4e7610f8a090eec8f83189aa3341b36b90254c6893f9b58d3e611b7de06d764f8db43c34ba917809ba2be + c8832fe8c57e993797f82b5a17e027e875e72ea488f8baa729ed8d21db907479; + f81d14517ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c88 + 08847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1 + 397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146ac + c3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d + 74730c45d4e79313a2d4dc9fcaf3b1f00d7a79a35e3cb48139df5572d7d26384bc4547b53cfe81ae1e756a1fce648140acb0a11a9bff1b4a36e3937cfd01530279be056525885a7e33780f3df2404d44d866e2b968bb703ba65050343cce7ac7f37f17d3ca + 92dffe3138ec6f4100ff81315d0e0ed88a060a3542e6501979f34cd57c8d39fc; + 98edabe08485290a4d87d13b + "" + "" + "" + "" + 5d70d40b83d7893de0ee19cc043d24f37030e50f04e4670543a7d4bf20fce7fe; + 07398a1458c2c6b61dbdbc1c + cc + "" + "" + "" + 46eaab4431b6623fda169bb2106f6facf930e13c6484bf477e1d2f81e4134205; + ada8c1a0a9aabb6c4e3c3554 + "" + f8 + "" + "" + a9f67f2c4c00e287548b6518e7d04080973a60280a52dd2c239c63b2ddf3dc13; + fb1ef61614c270295dfc0ca6 + "" + "" + 55 + 3c + 9ddcbed5f12c814a6b3cd8c58e52bdc8de3a56e19a764633c48d9d1087b0aae5; + 1ca4bdb75359f91cb9d92105 + 6b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f + 4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f64b837 + bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca34fd6544bcf86b799e + 876d50aae158510c3d5ef05417d3a1532ec91e08ca4bb7e4abe971f7c37a8664b39483eb2754b99085dd6f33131571ac6132cb202eb43bf75cc87b0b8848ace90af17f93c4793b4cd454b84ccf6bc2c79cd9c5c4ffa670dab2db3933e0b5a79b + d6e3a30fea2cb62326007770a28f211f7bd318ca7b4b1e2cdbbffe8b4e5f4aaf; + 2a1681160ccf055f0fd3001d + a597a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa96ffc3 + d1d2e31e4e34c94b8bfae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb19 + 01ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb84241986c251f5b70be2367f047265264e0da72efe8995e6c932a17eab511eddb8e4ba463c663035a6ae8a7a899e4279d54d03f0 + df7563a9736256abeeb7e528afd5868258e5eaa52b09d86eae63321459d7b39a681aad1b3ff8fb742a54f1a07d511162e9b282e50e24ffb8a3ad99b6a284f644cf82fc460fde1bbd338510f55e14ace30d831b9b7339d8129ce086330fad250c6091037555 + 22faf1c600ec3c2e7eaab84d8fc7b1a5fb63ef32d7161877da051ebfaed826bb; +} + +rijndael256-gcm { + 60d7bcda163547d348b7551195e77022 + "" + "" + "" + "" + 155fe406a3e36d08993ed00fcf78b03f9885b8626ffc1c4005c8f54a41d46bbb; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + "" + "" + "" + 5315b508de9b123b9d77bb1999fe58c3ec72ae1e8beade22bdfb1375e9e18d1f; + 8f86edd1dc9268eeee533285a6ed810c + "" + 9b + "" + "" + 6e1adb0aee567f8e7b58dc7acacf8e2a46fe0d4607e84afdb57725a4c4c62f8e; + 689daaa9060d2d4b6003062365b0a543 + "" + "" + 64 + 6a + 414c6496cbca39176224573e7c509b4f8df43e5cf5a02344cf75a5ba418322b4; + c76c160f11896c4794846ecfa14a7130 + c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f2954 + 9e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a8 + 94476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2 + 8a0b21b3faf752a732569ab7ca7edc0abf9ba5e9700cb599ab530b374c93ff7825252d41a0eaf26f6eb98fb43ca7e38ecf59c1b6a008c290550aa1fbac54233f5dc3befcfea5687b7516511137cbbbda3bb51357375fae4eb18f948350d4e9b4 + c70aefe02e2accd4c5e7567b52e38d2f1cd68d2621cdfe4303bee6ad1285ac57; + b03fb648e27fff63102758fe2b69ac26 + afa3349829b94586306fed54154f8f28523c03d4de1600157846b710 + ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f7 + 0800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc815178487 + 4b27aebc1cab373e6f5f94978fbb9dd4ab846dd4c8e6659351837bc075a78d472dac621172e1c5f4c0c184381cac80f27999fcddfc597dc5f1e96106f4c974d12d3755de2be779cb06402712144fd67538d2278d7c79eaf7e965d62aebae459883e94598ebc722fb5f + 91201ac6618b71df23cf770cb2be511fa68ab0bb4666fc5a0f166c46fcd2af60; + 3f0eb5b647da6794c18b5337685a96ed + 65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd21 + 1499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e61766 + 9c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0 + a0359a3a7cd37068cef9616e836e0dc51340c61800a8ca0c9a4e9aec807ed440cfa72d61d992bb4fd1ca3437804b9d3faae47b32aa37b2a2ea954c2bc6a4dfbe55ac20254bc6e65e257316355e37255c3358c287f9a85a809b1a339f928c7bc17d950fd4c7 + e1169f11b3af523780b7d6060ff7541119b99e149254be2ab460870fb20e0d8e; + c6f21195a3b9f4ae985511265febd11c164720ee + "" + "" + "" + "" + 88853f7a89a9d6ca3dbc23486aeabf94200f7b0222fc7c571c1124d33ad4bf09; + f9eb1c8dd0b00951f284649016ed00456331854b + c7 + "" + "" + "" + 705d0df1dae2209b02474644445391b9e6196b397ef49928be8dce7b1ba104c6; + 8bf43966eb0cfa9138ddc39908445608fe95e81c + "" + 25 + "" + "" + b1bfbd95d722b50e894535c7eb30e1dadb37f0c0774adb40dbad72e986b9e36e; + 33e31c9c1a9851bc2810d858cbbc8424d126b807 + "" + "" + e6 + 20 + 2cbef7fa0a697ec89874abb08dd7230ff6fb9e0eca0c5a694cab36328c8c95b4; + daa089c3f9099c5ffb824173d7634c04226f30cb + b7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3f + b90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b68 + 7fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65 + aab8f6ea96180e63aa3855416f27313b857947523e7341af0f8f5bd496ee8911a3dcb2db4514168dffb034762a8085a0785e79c8a67ca675f114e9846959d67fa3a333fe4bd09f7a118d2b2571a4a20d8c97c6e9428715a0fcf86a684d22faf5 + d3bf734339230e22db1a351306eb33335985be58380bfd61d1fdf52067ab901a; + bad397abfaf529ee41cf9a05c7efedef3401539c + 51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25 + 014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891 + bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d + 18fbf012c8917f257b87572611b9618701201d22196532e1fd0375bb15585569238d33c780cfd180db25b82bba0886360b0d8068858473f594f4ec46c069a8b5367266a50cf5b11a2285d4f11eae276d1aa24d0a2ae91d6e9d58b3d342ad1cd576faf1617d0b9ef982 + c55c8221055fdf8cc4ff383c13866d83810e0c355df37b4785e6bd3a260e961d; + 405e51881e99027b8ab9aea3ccf860b000974076 + 3d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9f + c214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f2 + 4e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d14517f + 6efc84f2bf195615f673c68a0e16fca98d6d9a156a74fb40b74ac9fa50db8c0a34d5b00793827ee2bcb942bea89ba023867de0d00f5d3066c10a035c5f626a0bd92da3b57312ff0e78fc6efdb08d7421a68ee134b28a684ab52b84f9f629009921d80ea20f + 1fb7f4fbc9bfc6b37ab7006cd6c661f5d8151f71f2e510af1edc1cb27a97c19e; + fae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c880884768921 + "" + "" + "" + "" + 5cbb3eb9742ae2cce92f5e5c9e6fa1875edb5f6ee2207e3ecc61c06370f81105; + 1450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a + 79 + "" + "" + "" + c1b0dabf513241d592852453e603c0325644288f76937abf90c8b53cb484f508; + 74a1d7f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44 + "" + dc + "" + "" + 9b8c23ac703837dc613935ba7bbb64343e29ed170ebf189cc79b301a6aba61a8; + 8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d230 + "" + "" + 1b + ea + d744d421289bb50dad6cf39990222ffd62c6cb8d2a1511ff27367827224e6eb0; + 43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de691 + 46acc3ab6cf8556b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d953 + 9726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1ccc + ada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cb + c4a2f019ff18e90fa3cea69a2f34f2d1f2d498af1173c860fa6b6f20e91781ecdaca5cd4f674027476d9cfb5b921c2d5686d1bc581b70b63feb8042f4d30deeeaf44528b6cddcbaf9a5d6ee4144fe4be1b526f3ddc573aeefe159ad33b9677e0 + 52b3da4ccdecf74bcf3d144ab23854db12a64df3ed547b78da9214f373d9d5c8; + cf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3eb + d66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867 + 642d25d54756fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22d9fd + 881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf858f938f6d + cddb79cdcae1c1ecf2734f18295a6e756c73fe54e8939cc5f0f47a3f543800451b17bba62b7af7796674b9d882b05b9b1d0c39a0dfaef98c54f64996105972a740c5a7bc6bfabc63e7d6a8b0924129b9552d6b0ad95028006889241b670a675e4545f21b6256bcd7f2 + 36fb5ecbc6a1f55d402f7bdb27f362b41cf037ba5b0c8b5f9a8c5b56da81e4fb; + aafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae64825ecd7 + 5a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e88fbf + 433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c1b6272 + 35a2cb84241986c251f5b70be2367f047265264e0da72efe8995e6c932a17eab511eddb8e4ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd40088d5be74088e4097efb0368c7e2f431ee6988cf2a0e9ebeb3de79c4f86c9e4fba61339d6d907e + 58452492c095671447a7c66a0e3e53cb2c2f6d5d9258e3a44f7e04cbe229248769719166680ff0dbf7d06ea1162b23c71aab1b4732c913bd542d952be48e1ff46df1d55fbad872957481cb71c5728e201cbec2fdc4a58bda26099d3bc64f1c6418c68289f4 + d9d12a477bc9a18f1b3a4a9ee2b289ff2ea6fa36758427bf9d08f9a4a92b7008; + ab7707ca48ff5ba1ae93d162 + "" + "" + "" + "" + 3858f6b0bba7f351a9ede4c2b5fbd5c827e7e992c079ca19cc6f26b830a9c751; + 25d469de5747bc1addf57487 + 29 + "" + "" + "" + 9fdad124895e10fd8b53e2064b9f2b9d2b3cda627483e9603549c80253e44688; + 720a320fe14fd29cfc59314f + "" + e2 + "" + "" + c34c2d5413bddb6cb1ba41791d7911bcb2edd49b6d71773f1454961f1c62033e; + 079c0a2535ded56112d6e3d3 + "" + "" + 3d + 6c + b700b74ae722b913ab72d6b1207776e402d74fa4845d602768cdc6deb15f843c; + cf7c71cd7d130323794e3da8 + 4a9df69703a9caf02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd18c + 374fc43581d2f72a89584a2404a059f7f99c7241a0c879d6d4455b382a9ce757b3e7a1d07585ad9d7ea9c7c9cf54f3bc6d94238ab56d738e02abd651477cd726d6f3ebcd6fadeab50906642a7de6496247060e7be3632ed9bd94bb42f45a8733 + b2cd2df9d1d905cfdb29983050d6bcdb686a0c897031ad09a5b8fa687ec3bad8e18dc2ad361f1e226e78876cd35f86c639733c5cd84aed8aaebabb7e0f24edfd9710b7bca91b612ea37fc5cc09f7f62f66b423fcd2dec5de24d264f2c839839c + 1e698dd38df7f079f6b406910c4c878e2605fe149c9a4f7d575877ade356ef2507eb11ad763a153ef93464f72fb80ccf6670651a22532662e1e33beee419e8a82c8e5f1e723ed1c0db76e90b94a97985e01ddf0b10719a689286b0cdf217760b + 7aa4400ac56abdd5ed32f35f5487361a090461e342f11168b122369d31860f96; + 1b06319f687dbc68d9f07fd4 + 1ccb4f8cde8de201ec2680332bbded4883deea0b58b54bdd13c17ef2 + 92b0ded3caeb5e57fd21df10bc6186265ee6ea45907de6cb822fb2ef953aea358a03e0 + fce2e1b9511bd332c86e67f123377a8f0256b8dcc73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7496993a25b072945d83f923e66b0a6689cf0969c003a8fca80e322a4b1bf050c1220450433efb6b6d8a2d820cf27a64b9d47f636845dac557bb3e75f3a + 10d009d35f7cf513d0f5045d1520d92a4971e792b83901e518ed440e68ed1f4eaa251584ce7703195b3f2d0b19ff558713922efe13ac3e8f8a5d7f608375326aa7a7499274df4e3c963007805ebd4b66c8c52059844edf60327144ab7febb0acc2dbcc82795aef7dfa + 02dfe024b324aa1ad7a4a9f1d1cee9c0ba3711e97510fa26ba8f87f7e195bc4c; + 18fb8e173416867fcd0ee78d + dd9236beec76d55ed58b10f91d07a037791ab96e83c4bf2fb5b205e592c172 + a5cbc19456c95c1bea6079f3867e52d663cb3884b2a0a8ff825df752423f3179bfeb89eca385f20ddce5f1f23564672e370ffc37d400a31e8aac1d426ce10df73c5ee478b3b63d91024780e974a8a2a0e7a36f84ab1286b627e7d0 + 1b38a84a6de738721ed80fd0d7f69fa658abb5a440d304128719b541a9451cead18e4c61d93d1f8fcc53574427767396322b3bf7d02cec05093696cec07591ada462271b1d1519eedde0df37a330fe8c22ebd77705917b7e32ae88f45a34a8ba3037235e19 + 4c8ecebea3c8b010464c18f765a3e100014f564146cfb6382d1e60f5727f37bcfd18f0227c1cc3817fdac6aa202fb93606338616cd140f999d57c36cbfcfd3eb38fb4c4cf5e34a9f0a16b703d268c428e4b3a2b26b4d3a19b08b5468632020ae7cf98a5b6a + 305e9c670143f7d88cefabee533e27ad48988b607be91f0aa2f17649d629b688; +} + +rijndael256-ocb1 { + 60d7bcda163547d348b7551195e77022 + 907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed81 + "" + "" + "" + ed3e1a85a9f92797e1fecc6ea6840a3e0474ce6a9698a720d3df978f3528e06b; + 0c9b689daaa9060d2d4b6003062365b0 + a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff + 77 + "" + "" + dfb76cec6a750934ea46b81a7e789faca6d7dfb9da0476a03762f15639df77d3; + bf79192a5b50ade5d9cd739a3d1f337f + 29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd883 + "" + 74 + c4 + d5bf8b3be61be60645f84da4eeaf832f082a8c0d6ffc3cc3dcbe0b59bee9de13; + d8cde8e160ad10997a21635c6d62c926 + 9029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e5 + "" + 05da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad + a0403a115ebc9ec954f8e240c84a2c9c41241258c510be90585ac99233ae5283d3761b07c48c4c6ed2d445d16d5db78c50e54f9866ba1d5259a887eed0f2efd3c93d77945b1c03f8cb8e30ac431175dbb47f03d3643708aae7f0a329eb433b58 + a26972939b8f37a37fbb8444db5fe6689b857b639d7b54246144435926e265a7; + 54efc9a38378c5b93bf4f2aad2605fae + e2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f + 28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689a + ef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e + dcdb20cd5e1952a7585ea1a5982f5f52fa76a949f615460c564c1f19106a7d06c5b1b194d64d000a368d353e255edb34e405639298630f6dd09210b7218ddbd701c8d29996da07df9ea188c3a58f8f924cae99a9a04822d148b39e396eae384d + 4e7b366cc5683e7f8687281003d4c70f2167371aa3cedb3aea7c7b8a3a4bb8c5; + 23e6eabdff3bcd211499268878dbf30f + 1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f0 + "" + 83455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a6 + 158feb4340d051637c994afa715876f75eb2f49e832bf4a3d8e7f2d7268f4050406b13952ec6aa85123767375335c65e2651fb803c3399c5f51278c0381b942c575470ef2f2d7a3a003fc174d62c38d4eabcb7108adf2e2eaaf6c74e13b759f37fead1fdcc + aaee630716b5f9a791a7941b640408defde3f1747b50bdecde2bf82723fbe523; + 84b5aefa69a4cd52147ed12ca986981a + 874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472 + a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9 + 099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b + 374a36cca45ec0f3ea9cc9bc1fb67b6c07a8ab781d118ce9d56988904518f853d2f7551f61b0d87e5afc19c5e732dc0c7d7aea114bb3d7af88cbcd21cb7d06a22eea30921d1277e4e4577152497ff59ff72e55156262bdde9729721c2dc467afb977e5ee63 + ccbfaf10e2aeade3c72d7f465c271105ca36369bb2644d6da6706702fc8601bf; + 8f0911e32d65cc1770a18cbfe6effd1ff6778554 + acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c8 + "" + "" + "" + acf282a61dd79a7e99740e531b665b12c199e0f66bc3f11f4a08d8fcee8fb713; + 4cef64f6c9b53bf8f957f4b03cf43e89957f9a3e + 8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b085 + 1e + "" + "" + 86c6f639096f603555766a0a95549f99fd21ee543f9fad5b44d644c96114e172; + 5ca605ac8451399587011677508a15dde524af3e + 2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef340153 + "" + 9c + 8f + 51df0841f87c0475e6a8995ff30422fcebc313107123f17dba67767e0dcff519; + 51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213 + e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec59 + "" + 0294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb + 0a74784147a1986b028e29a9b9ab25645be3d7cb0774e9e5acfbaba28742a47196bb5297b70ddfbf10ce5f1517abddcb29d0fd5b715601a795af85d5503033a19bd63c2533fd50f3bab3c18fbbd7894242f15adad0f1583a5a63ab9745dc712a + 9f1f55ba4cb8865c9b9f839183519a3b3c0bb4ecc294e1ea248be64aa7f48f08; + 3542a9cf44bbc8c6254d980398bd94e66eb4563d + 405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1 + 288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f + 834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac27311 + 882bc55429939372f9123390b69f5ce58d26d439fef94063f8b2e96ee4dd8fabd4e9d886e1a1362ea2f95e6e9691c0ddced94c5ecc54893643ed0e75660d43a19a2dff771b1154c860b40d50d68f514c94ee102a17dd347f81954c6ba2266cfd + dff24d1115cd7f5f41e72a4709896297a9cc05dade73cb71ae7b26254faf70da; + 7b45bcfff5d5f8b6fde2893232a9f81d14517ffa + e475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095 + "" + ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e56 + d96d78f641edc2bf6b208202b51ec76d956f5df89026a9f64d9266a2353dbb708b28e63a6999c6adcc265ff3d348d648196d3583e5af294a9bfb31e310f151d70ba5c9735224d768ec4f9400aafcad9aaecf25fd4cd392e35e7c00fe2fd8787deb07f44d00 + 94837daba7fa8fd70cb03d138e2f493e3db5c9388cadc8e5a6612075fe49b300; + 0475cff206877de69146acc3ab6cf8556b7aa776 + 945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39 + b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aa + bb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cbcf96523d4723f91801325e + af41f07118ec731dca9ce6df290baa0e5000c68a380a9572679c32437509525919c9b04362bece8721d10aaf0fa8dd9a5fa9f3770c5d5ec1a0deae996255b61fb81f894a521f939cca36fbd9f730ab0d0c17d0689f8c1ee78d4707a36c219a0a60c3fa2def + db0e21f651cb6892563f22ec7d4e04c8ab46c22221819f3060f64c5736ee06a6; + b8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de2 + 5b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f64b837bb + "" + "" + "" + 9f736b72141985c5a64c5888c112a3c872497e54cb822ec3790fc73055d5ee58; + 4926214211a1c696ba172010abb433922a22d9fd881519165eb9d851 + 97a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b54fd9d70c70e117bf + 1c + "" + "" + e7b0f52d7adf83fe817103f61ac846a02e957786c5e605057e41fe4dfa552948; + ae71b3a56f0e7d839ea59cc783443d64f2ed6a29b96856beca34fd65 + 44bcf86b799e2a1681160ccf055f0fd3001da597a1406d465b7b1419ea51cf85 + "" + 8f + 2c + c93c329ab8f440bb37247f60a5370b34d34ad7decec8e6b2d160acd4c1d12410; + 938f6daafbd656445a09898eaa96ffc3d1d2e31e4e34c94b8bfae648 + 25ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e8 + "" + 8fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ecfc8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c738f4cb0f58a1e34c8b15ad930c1b627235a2cb + a213a44a04d450838aa1eff21b53902349c2af2ef7e104af43fcc781b42c9ba22cf484ff71dec347a3f15c73eb2e644fd119297807f96eb604e32bfc76a2dfc2ad53c2ea3842a06e625954689df48ee180d465a55d5df9f2caf89ff7583e6a6e + d09e13109159cbee4f1a32379ea1daf61be14ef11778514d79a403df22b3873b; + 84241986c251f5b70be2367f047265264e0da72efe8995e6c932a17e + ab511eddb8e4ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd4008 + 8d5be74088e4097efb0368c7e2f431ee6988cf2a0e9ebeb3de79c4f86c9e4fba61339d6d907eab7707ca48ff5ba1ae93d16225d469de5747bc1addf5748729720a320fe14fd29cfc59314fe2079c0a2535ded56112d6e3d33dcf7c71cd7d1303 + 23794e3da84a9df69703a9caf02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd18c374fc43581d2f72a89584a2404a059f7f99c7241a0c879d6d4455b382a9ce757b3e7a1d07585ad9d7ea9c7c9cf54f3bc6d94238ab56d738e02abd6 + fcc7943e60d8714fb6070f0bf3db4215b5bad60d25f36aec66ad4ab1c8512b26e5075077d4685495da25e954e00972df8f01ee3e9a6a29ee9d27f45bef2a2d975fa0e2736b59f7273df0489bc440883bdfdf55cceb03bbaac41c4b92bfe099c7 + 72230dfc699fa95374349b8ab1e55f95234d8f8ffb80eb193157746d5e28f670; + 51477cd726d6f3ebcd6fadeab50906642a7de6496247060e7be3632e + d9bd94bb42f45a8733b2cd2df9d1d905cfdb29983050d6bcdb686a0c897031ad + "" + 09a5b8fa687ec3bad8e18dc2ad361f1e226e78876cd35f86c639733c5cd84aed8aaebabb7e0f24edfd9710b7bca91b612ea37fc5cc09f7f62f66b423fcd2dec5de24d264f2c839839c1b06319f687dbc68d9f07fd41ccb4f8cde8de201ec2680332bbded48 + 1c4d9a95f9cf85283b59197b0449fa65429a7de12cfb25453f01b0f7afcc5534fd6faa80ecbfc8607fe7980370d3042421385d7c684ccf71d4170db54359fcb4cff4d2d6126b587fd6b2b50279ca190f605c740546b2a0a75055c0cb2cae2506a5fd23be2c + fccd1e6489cf18fed4f745338cb06d0a61a6c692d72bbab24b3fa0ee9e9e2a88; + 83deea0b58b54bdd13c17ef292b0ded3caeb5e57fd21df10bc618626 + 5ee6ea45907de6cb822fb2ef953aea358a03e0fce2e1b9511bd332c86e67f123 + 377a8f0256b8dcc73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7496993a25b072945d83f923e66b0a6689cf0969c003a8fca80e322a4b1bf050c1220450433efb6b6d8a2d820cf27a64b9d47f636845dac557bb3e75f + 3a18fb8e173416867fcd0ee78ddd9236beec76d55ed58b10f91d07a037791ab96e83c4bf2fb5b205e592c172a5cbc19456c95c1bea6079f3867e52d663cb3884b2a0a8ff825df752423f3179bfeb89eca385f20ddce5f1f23564672e370ffc37d400a31e8a + 277fd76c5b58942c48687f4153c8d8aa6521902cff09bab07145801225bb2823fe4e112fcd11726bc62da7864baa800905c9392017a574d966aca87da54d481e320934c4d5b8858bb53c9f91170e96edf3e3b6a583677e2eb0f6e876162ebc2d9f9d5f59d9 + af850a26c1eaa2af0c507d84542fd2a5dfda7ad3f6bbd94d7202716f0bd83b66; + ac1d426ce10df73c5ee478b3 + b63d91024780e974a8a2a0e7a36f84ab1286b627e7d01b38a84a6de738721ed8 + "" + "" + "" + 1a65a7de04f027cc7ee41a321985a03044b009409ea0a04a6ef4f268a40d647c; + 0fd0d7f69fa658abb5a440d3 + 04128719b541a9451cead18e4c61d93d1f8fcc53574427767396322b3bf7d02c + ec + "" + "" + 2257228003251d6931be43f6f65654859ae865666736fc80b7ce6feb69cf8c4d; + 05093696cec07591ada46227 + 1b1d1519eedde0df37a330fe8c22ebd77705917b7e32ae88f45a34a8ba303723 + "" + 5e + 44 + d4ef8d10bc4dfc028117bf6b79fadd4498eee972464c390c38cdd44837eb3a8c; + 19a394be4d26ce47317d8087 + 684456b4cfc5555e925e3e7b2ebc829b2d0505ea617b0ca9531bcdb96040d390 + "" + 40e632d562643ccb64286303040fcaf679e914eaddc05af8843ce6a427b99a5dc266de31c09165237eeefe4b58cc034b9f099f04678c2a9da898b39324cd3087a651014f6796f9c4881d89e127e62221e47e57badd678d490c2f320ff8fb1c42 + 2702a4cc524f8c7eaad3198222eb31272dcbd5885798ecd2767a8e9292550feef8f1a6ce4c615967cc154def805d429a2964b5202955972c106deee2444df7dc0a3ba8940bff435cde364f1a43e4e5081d6bc4296ffcc3f907152b1e01e892ea + 37ede9a353c66446268a96e3101e6716b5a0875413bf2cc714720277885cf14d; + 761bd439f3e96dc0ed1d5b21 + 69912af1a4e2c533c52ba3e8c71c23a089e231480aa63c484fb34bd522397f10 + 2cb8ecf4f64e329884fe73be257a753b38200bc23f94a079bde2dd98d813655dafa15b85419d15c41a5153cce5d0e8c8702db2ba11927589678d4f7b8fcfad4818c411f15f452300903874f9a532ee46496ae753a2340af7b91f9632fc5ae71a + e18b40de751ab6b6761ca16434a9935e466e11c1cb072f32a59c313dba3db646ae909a096697d9a7b0556463ff1126ebc43263391424d02739d0787e804d8f1dccf6c897a8a48431324324041b5302ccd501b538bd03d5cb5c90d1fd3f7d2be1 + f03d990fa20cea58d5d15c20a6a8479f8a2650c245da7d5e8505e2e32c924d6332b7e8cb40139bb17a2b6b95a200c1f4cbf967ec5ca8bbd04db6f70a767067d46fcbc066aeac04f2a3f9e647b290d31f3de21a9dd0e757274c1623319d1f98bb + 129dc99b2b2d0335f5453ba882fa4469e4617169fa9f3394fbfeb4a9fb68925a; + 87a787032c79ed900764ee4c + e1d3fc042c084f7d8c0c48ad7d6f1eabd0fd1ec24a88f26734d5c8d92dbd873a + "" + 8fe113090d401bea4d28ff49f10ff593adc258e091abd31b62dd1735158f98765970acc6602da063aae01a2a199d3a4f37a5f062d216d2053a83b5d3a0488ab0d2df631b2892cdfcf9fdd0f37de9ed67179aeae82fe00009428b297b553230a6d917fa0c1a + 7e3a6085662512c823d6d9929dbcca2e1833f6589a38fba924c2e16d6a1d050b7442fbbc2dfd750c76235c96aef4d0d9388c457c5c368c58325aa09623297e6c4a5f19b668ec3ace50bad6c64824ccbb0ba3c72fdc5041ec93d3f231321f687906e3ebd93b + 54e6538ecb2b4903cb6f375cb5956c92de38b1584b08cff45916a3c4b1f5ac84; + 233c9ebc8a4cba45b20543c5 + 40fc1b9dbce078b87a1534acf03897b95a3f372e9f6c5a5f2ae44a7dbce9ba43 + a39089de20de70d0544b5151db0a16e9769e8f2fc12c7f839fab269a0056284a697ffd4113a1cf43b5d5bdce2d86dead83f5a356e9106bedf908db61f1119f9700260ea9379cc7232184d217158fee8ca42e75614739e9007f234f + bcd86b0ad8f641a0449b6d9b0f99d1cb4a57a4d6f987feb0ade90aa1d81c4f497b3734be301da3e25fe692629db57311f422f3a1573f9e0553a23e96265e4326fa532d7136863e5b4bc6c99ade3d4eb23cacdf6e42ad8ca13187eba1532920ba31582b3793 + c65596e9c53e56de712143c2be771a3707bce914410b2e32fe484f74a6210d6ccc48122d4df80f2fdf5b3da056b8742ef07b5ed7c038d18d61da0f5e6584c6af306d1e11ed69ced0594202b10cde788cfe963d38846daa71158909e5fc051dcd0b11b2a8c3 + e450cf5a72fbfbc72c1249de355a6c3fd6efbb4bf28f68c48b286266a7a2ec6e; +} + +rijndael256-pmac1 { + 60d7bcda163547d348b7551195e77022 + "" + 932f0d9371e20b910a772eabeed12feef4f4859c0c0d15200b2060df6a3cb6a2; + 907dd1dff7dac5c9941d26d0c6eb14ad + 56 + 9a97ebc929e438b9781ce3263e5f78f07fc74cf685c00cc7e16977985459a03d; + 8f86edd1dc9268eeee533285a6ed810c + 9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd883 + 27ce94c2d0af1899c43ec264b5ae7ead31b2dd65f45f3fe0e95cc0ac6576f672; + 74d8cde8e160ad10997a21635c6d62c9 + 269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52 + 571b59ffd88f5aac558bf81218c3cb2fdd9e800b3326401c649e53bd5a406f57; + ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6 + "" + 2efae48af6eabef0778e76390430974fbaaf244c3fc6bbdb1e58b13bcb580fb7; + c95a97a48030370c33d090c54215abd6b3ad54ef + c9 + 4aee747efed92d046967d15c7fa52ad582133e03a0a177ac602ab5666e5c23cb; + a38378c5b93bf4f2aad2605faee2b03fb648e27f + ff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2 + e5afbb13c8243b7c984eeaa0307277e7092658217292fbf05e8d0a56e3fc1b21; + 712a199e533fa9156308cdec3f768281e040a9b9 + a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c4 + 913f5198775e26d1e0f6c2a2d05e26b280f7ddcf117f19afaba1ee0da1426e70; + 6f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad + "" + 1f93abf128d33b355c0a88df509ac50535f22ab4fb12799f703517544aa9acb9; + 89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20 + a8 + 3f86edb2b064d7d351daf60764c151d2f8759968ece6d3f000b792f6c3c92faf; + f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f + 1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abe + 27080744f866bf654524ac485f602841ee45bda2e22542f55ebee2e275952bff; + f8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784 + e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c + 17313b005c8ed5153fe443e60220e8f21373fccd865532655f15d74393767da0; + 5ffb824173d7634c04226f30 + "" + f4a17475609b3057cf1af06d015538a527b56fb849c986850c224ace1775cbab; + cbb7f0e4a973a8cd19010731 + 47 + 74a4cd7ca684aa5015445562c68f2c4dbdf63d4ac5fb0f392eaf16b533fb0304; + 17a77456f3ff669c732b58db + 8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a4 + 83b54ce5e25f2c786bf25fe30336fd71900040f048dba6e99d175ac195510fac; + 58cb948bdd409b687fa3a682 + 7b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d + 631ff4d45f8f6536dbc36c29a857d440c7769e87829b468e051e0de73f82940a; +} + +rijndael256-ocb3 { + 60d7bcda163547d348b7551195e77022 + 907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6 + "" + "" + "" + 94cd6ce38b3c77d05a0a0d25c295a65a6b7d7dfe954b0cefac92134d2864832b; + ed810c9b689daaa9060d2d4b60030623 + 65b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c95198 + 48 + "" + "" + 405c363c87384173bb83480d788161af11844656e9cef376f25b82bb5e1c537f; + a877ff77bf79192a5b50ade5d9cd739a + 3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d + "" + 8f + 0f + 66d804966f42b17b54de7c5c83254b129c4ceb4a428c76c4d8d06cc3efa3108d; + a21f2dd88374d8cde8e160ad10997a21 + 635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3 + "" + b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a4803037 + 874bd486ad241e305a5a00887137d77528095262228eb73fd52f1c6e6313600da01bf461d676730308c2c61feb98f1cda079b3b4372c6c3871c434c75972bb12fabfd29bb6253fc54ba1b93a30fd2bbb0d8552886c324a268afc3049aec44900 + 5913eb9194f12a3cf55bc082c9dc16ea94539318585e88fb31cb62f6732e7004; + 0c33d090c54215abd6b3ad54efc9a383 + 78c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26af + a3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cd + ec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b + 0ff57de3d2cc21519dd3d0f49fda28b2b5be55e284d48d36e5cba568ae1e8b58fa124c37912109af141b0f186c2fa348b62ca46c66b6889aefe7d2feb01a0379069e051ef893b2a1b40d67aa04b99c53ceda7b3bcd2b7981638e4d8a319e8283 + 68dbfe675410e257abc994d87e0d6b3285ef039f4296e4a3ef6c3380e8b9d057; + 09c063c46f88de9fd41e72d7b97e23e6 + eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e + "" + 7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c + c5cbe3643d4234720636c3db98390cf32199996b8ce59bc07885a360d5cfd002cdf9be271301983a242a71f966668b54deb6cc8e602c11b4db33b0ef65437bfdf4a92d0f923f9997c3c74c3d850b8a485615e0b50b07f76cb252602bf211492cc980113905 + 5470a7b06cc51ec77c63446ca423d3153633f1957329423be3a685b42981dea2; + 31e6bc58c0b7cadcb658b970e47479a6 + 84b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98 + ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc + 2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae + 870e6e1f56383e064accc0744f1b450d79455adbc72e49461ba13564ccf944450db7425db27c41f82bb0a36397116c2cd1a1034920fa12bdc9d6fc62cedef298195a8e05dd34cdef1726048ee2d8c9ab7d5f46f8c9446baf704c7755f3ee8d91a6fe91b14b + 67d3c0473bc44d9ab3f05eb918cb7161773a63428d9d399854041d31168df643; + 9ce021a5f1fa4ffa91544485f1a1258b2b9b8f09 + 11e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967 + "" + "" + "" + 220a303425f9a53ce13518047d3dd5d8a1d2109ac835eceb441c5a586185f99a; + c0a458cb948bdd409b687fa3a6827b480aa3a4c8 + 4cef64f6c9b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8 + de + "" + "" + 7c5abcd9e9323820d615abf862549cc31c1b4e1a1e4da3e5433ba6e39e5bf538; + b9bd205b70e04c091d205cdad9e9a79b1abf91b0 + 851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2 + "" + ec + a0 + 3fce0fc48d3f0d7643ebeed0d4717eaaec3f4e2dfdff01a8785fb143e532f5a5; + ccb44d65bad397abfaf529ee41cf9a05c7efedef + 3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e + "" + 8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde957 + 61bc90511fe93f33ef7e6ab4413c9a0316b1c5ed6f08f6b01242a31e226cf226df4af92db146356f1085cca26df2fc170b84f4b8106ecf2d83fad1572c3be1c30bdbf150035a6133b3ca54639084608bcd0aad6999675b63f2550129a01dee57 + 3310b19ecff1df1ec1e41c327a823ad057d4f4f494a867a029f27be5f9c540c2; + 59ac46fee6dda7abc8ad68daac90cfe22d2f1f29 + 68cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d + 405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf + 1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383 + 134807254d64c7724ed92cdad040f7f59a768628d3d57c45bd3eceae504854100ec839b7c3ccac4e6644fad7812fc05834435d690b67bedb6f4801c9c4ae2d8fbfb1c879e6546e6db284071ed8ffb46ea8969dd3ca48cf3872c1a7d80ceb46c8 + b379c41bb4390d6908cfe111a9dd6dcc768b040ffe4af315f3cef5e0aa8c86c8; + a8cffeea7c486315799dc875fba578c8ec483789 + 8a92142b5b0677da1ac273117b45bcfff5d5f8b6fde2893232a9f81d1451 + "" + 7ffae475f6b94a43a67b3d380d2f9aaafe2dd721c0095c8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74d + 7b5de357d72bd4a66e08bdf26b45f5d47e4c4042b89c239682d74e9bb1cd0f544aae03e377c97b30688249beb16e2e43d82c7761d7e61ceb853ad2209c68b405e99283fac3df1c6c2dd8222a9adcfbe909f0fcd81692e36a49b04dc2b1841f26145fcf57d6 + dd6d1166ec2c7975dcdb49e29a3d55ae62fd37726266e884efea710157757b61; + c23a7bb40e7e0013e5150686d2301b43a15a84e8 + 1d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf855 + 6b7aa776945948d1b8834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa4dbf710a9e544e0c536ca1e040f9 + ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270295dfc0ca6551ca4bdb75359f91cb9d921056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4a + 8257b8b269a4660300f762471821ca7a83d067b72aba369efa0edf5900693daee8da585e8f41aacde010cb5efbec25bd2ad47c1112f5ae87f79180659f3eb86052d760392fd1a268c2e75ad6e6dc447f5581fbd2aaf41bf7120c169688c8043b3db9f8fc1c + 3d62bf30f4aca83ca3198e4d91e2ac40c9c6e5be1f6e02943f0a947022425d5b; + e480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fac7cbcf9652 + 3d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98ce + "" + "" + "" + 5f89715a1b8c7fb4fd3816b482fecf863fd5ffd013258827030d840fa2d2a1d7; + dbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d547 + 56fa5c47f16f64b837bb4926214211a1c696ba172010abb433922a22d9fd + 88 + "" + "" + 065b3d824cbbad977cf67a74c2dcdf3605309d86ab3df633aa3ab27347e44e82; + 1519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5 + aa47b54fd9d70c70e117bf1cae71b3a56f0e7d839ea59cc783443d64f2ed + "" + 6a + 69 + 9a88da0ce1b21c5c7ca8badc6b9e8e59ed577ac39b0af14fdab20b02dc9df442; + 29b96856beca34fd6544bcf86b799e2a1681160ccf055f0fd3001da5 + 97a1406d465b7b1419ea51cf858f938f6daafbd656445a09898eaa + "" + 96ffc3d1d2e31e4e34c94b8bfae64825ecd75a66d88eedb969ffe07669845ebb7a24c69f13d099f47166edf54538e88fbf433a7ff212085179e79771f6eee7283ab178ef2b800d7b969da05780ffc1ba78c70dda7a4ca2a25e771702fb1901ec + e3e73214e48c0326b4e390a35aa9c0d9a8696a196543c3bf9409f2675fedcb4b5b369ec744fcb5d2ee7a5e76549f1f9e2a7c98b1989349e37e82bed729c9278ef0a925fdc7c838535dfe0351f8d7b3be579c9b17382ab0720513ea9c485097c6 + ef9f792e7eff79fb841852ed80cb6b30429520d077bbedde0d797735230dca6d; + fc8a959cb8e75079bb018ccc8c54f31b450e88f8e9002926ad0284c7 + 38f4cb0f58a1e34c8b15ad930c1b627235a2cb84241986c251f5b70be2 + 367f047265264e0da72efe8995e6c932a17eab511eddb8e4ba463c663035a6ae8a7a899e4279d54d03f0e0f3e961dcfd40088d5be74088e4097efb0368c7e2f431ee6988cf2a0e9ebeb3de79c4f86c9e4fba61339d6d907eab7707ca48ff5ba1 + ae93d16225d469de5747bc1addf5748729720a320fe14fd29cfc59314fe2079c0a2535ded56112d6e3d33dcf7c71cd7d130323794e3da84a9df69703a9caf02d2a8f57ac71e554a6850d55882f8c7ae6994fc8528bd18c374fc43581d2f72a89 + 17bd1896ca1775f27a78f55e568ac95360963aa799f1736346c94174b2749d9626a2d11af0a3717f4ddd4bb7d71c27c834cc11973300b851590c28bc90e377b9c672be42329e4fdc2b8178f54727f529d6c6c973ffef4bc3d829df42e2913d93 + 0666959b0610c0e4390049ff5339e64bf450a485947e7ced421550d5b4237143; + 584a2404a059f7f99c7241a0c879d6d4455b382a9ce757b3e7a1d075 + 85ad9d7ea9c7c9cf54f3bc6d94238ab56d738e02abd651477cd726d6f3eb + "" + cd6fadeab50906642a7de6496247060e7be3632ed9bd94bb42f45a8733b2cd2df9d1d905cfdb29983050d6bcdb686a0c897031ad09a5b8fa687ec3bad8e18dc2ad361f1e226e78876cd35f86c639733c5cd84aed8aaebabb7e0f24edfd9710b7bca91b612e + d98615675232b1e3b446b8ef49645238f92b1286e06f32a6086476e1cf2636ee4591be6c515a03f84c5f5bdbf0550ad6440e5614eea29ff878fc7a1a59292ee7076722c6c12bd0561eb01666fc0eaa74acb29400ab1af944693f08c3df1202efb9aafa5204 + 4ebd32cea5c4e8e22ae8d025273d736a7aa4ea99ec35555379d29b64beb35275; + a37fc5cc09f7f62f66b423fcd2dec5de24d264f2c839839c1b06319f + 687dbc68d9f07fd41ccb4f8cde8de201ec2680332bbded4883deea0b58b5 + 4bdd13c17ef292b0ded3caeb5e57fd21df10bc6186265ee6ea45907de6cb822fb2ef953aea358a03e0fce2e1b9511bd332c86e67f123377a8f0256b8dcc73ae1b3c6cd3f104e3cb24284cfed17811d64d492d39ea7496993a25b07 + 2945d83f923e66b0a6689cf0969c003a8fca80e322a4b1bf050c1220450433efb6b6d8a2d820cf27a64b9d47f636845dac557bb3e75f3a18fb8e173416867fcd0ee78ddd9236beec76d55ed58b10f91d07a037791ab96e83c4bf2fb5b205e592c172a5cbc1 + d9971e97c6107f5e95716634e4731360542765a84d798c706f88a6dbbe83b4d0588bbea20e927524f8d21de8ab71a910ed5bae27aaea95bd20fb05563fca2674cd6037d9fce9a1ea0f47fae536d92b837aa391a5a8f6c9b4e5280b66553d7516df90b4bed4 + ed3bb7517af2601dd23e9c5b54c63eeb050f51d15acdaebd6bc47325ffd33ff8; + 9456c95c1bea6079f3867e52 + d663cb3884b2a0a8ff825df752423f3179bfeb89eca385f20ddce5f1f235 + "" + "" + "" + d7bd5a595d894ff087b4120947bda4fdeb956a41b2e9fe9152dd2071e11b0552; + 64672e370ffc37d400a31e8a + ac1d426ce10df73c5ee478b3b63d91024780e974a8a2a0e7a36f84ab1286 + b6 + "" + "" + affeb59e316bcec613e4ba87e80e83c1204f83e9aaba7de2263c76c1778c3c34; + 27e7d01b38a84a6de738721e + d80fd0d7f69fa658abb5a440d304128719b541a9451cead18e4c61d93d1f + "" + 8f + 5a + 92a3d896a62298b49df5d041c3f30f3ca01a387e04bcd3e4e934789fa270f485; + cc53574427767396322b3bf7 + d02cec05093696cec07591ada462271b1d1519eedde0df37a330fe + "" + 8c22ebd77705917b7e32ae88f45a34a8ba3037235e19a394be4d26ce47317d8087684456b4cfc5555e925e3e7b2ebc829b2d0505ea617b0ca9531bcdb96040d39040e632d562643ccb64286303040fcaf679e914eaddc05af8843ce6a427b99a + 984c933c9aa7fd8536cafe98d705ee19c027a3c82e1f655b87325e8694d8982e7da50abdfdda9b9275c6aaf0dd141b8f2c4fe0d4b32d1317efccf6a1768da9d15699af7c8fc90eb6386648e098795b80380933001d47f3484b771cc6435e824a + 300a77fde5151a0a55110605f648e984e5c5e9c297759b420773e0198fd43de6; + 5dc266de31c09165237eeefe + 4b58cc034b9f099f04678c2a9da898b39324cd3087a651014f6796f9c4 + 881d89e127e62221e47e57badd678d490c2f320ff8fb1c42761bd439f3e96dc0ed1d5b2169912af1a4e2c533c52ba3e8c71c23a089e231480aa63c484fb34bd522397f102cb8ecf4f64e329884fe73be257a753b38200bc23f94a079bde2dd98 + d813655dafa15b85419d15c41a5153cce5d0e8c8702db2ba11927589678d4f7b8fcfad4818c411f15f452300903874f9a532ee46496ae753a2340af7b91f9632fc5ae71ae18b40de751ab6b6761ca16434a9935e466e11c1cb072f32a59c313d + ed01665286324cdff1c38648e15ed6c53f9ad08c6d830bbcda44c1a43d662b55b65a02493a13da360250c8f67d83042de2a3cd4b5ef58d6de79ab9b29377377f43b179889b2d73a2a4bda38c8018504a3e3366be90700291e7f9d676bd764661 + 7ad70b7407fb23e1d1cd1aff53cbbd9b27b27f3d5323b2492cb700d6c336a73f; + ba3db646ae909a096697d9a7 + b0556463ff1126ebc43263391424d02739d0787e804d8f1dccf6c897a8a4 + "" + 8431324324041b5302ccd501b538bd03d5cb5c90d1fd3f7d2be187a787032c79ed900764ee4ce1d3fc042c084f7d8c0c48ad7d6f1eabd0fd1ec24a88f26734d5c8d92dbd873a8fe113090d401bea4d28ff49f10ff593adc258e091abd31b62dd1735158f98 + 13c29223881fcb5ac5bcbdfed11fec190f5616ac0b9a48d7c500416887ffeceda025cd1a53cef1b43980cf4930680e43727549984acf076bddb90b889ad22a81bf371bcd9b1bcbcb8e1709cce01ae25f6bf51424b6ca9c6f54cddceff6a536df344e96d66e + 6a5e940b5fd47e1c52ff1d6e898c535bafb686a2b12931f0d5e4a902207c5267; + 765970acc6602da063aae01a + 2a199d3a4f37a5f062d216d2053a83b5d3a0488ab0d2df631b2892cdfcf9 + fdd0f37de9ed67179aeae82fe00009428b297b553230a6d917fa0c1a233c9ebc8a4cba45b20543c540fc1b9dbce078b87a1534acf03897b95a3f372e9f6c5a5f2ae44a7dbce9ba43a39089de20de70d0544b5151db0a16e9769e8f + 2fc12c7f839fab269a0056284a697ffd4113a1cf43b5d5bdce2d86dead83f5a356e9106bedf908db61f1119f9700260ea9379cc7232184d217158fee8ca42e75614739e9007f234fbcd86b0ad8f641a0449b6d9b0f99d1cb4a57a4d6f987feb0ade90aa1d8 + 871ec85dcb564eeb30e76fa18d1c45e6e03a34fa8d3701ae975fe8ef646e5581e70a2d7de65b92d4407925500b00443315317b26a084bb65f2c3c03377dd68c814915a3215d72c409cbbd99261b6ef8d14ddc790a7a7495c7c401ab4d4041607f3f4320eec + 8c4b5793f59a300f6e01ddf60ff510fb1ea408ad470064a3cfe0b1b4931e6535; +} + +rijndael256-ocb3-mct { + 32 e6daf3cc9ccaa1b05a68b6069e290909301ba320423b3a658c9552e67486ac87; + 28 3cab36843515c14a36039eae083324d2ab843e04f30739848bd7bead795a6cd8; + 24 98706671cb1048083d2e2de4692530d8259d4ca91e6f4f995f41bc2bfb575e49; + 20 5f3ad3100cd757cba80500b2cb3159530cebb5b1309b89eff98daa458348119f; + 16 a10c36f02737879b67ae2c4447f6d25cfaaae27916b95e40d2f36a40f9127415; + 12 2b848a4d1f15ffa8a4937abe0bf244488eb69962143c49e942fabdc21bf05bca; + 8 450a06d40fbcfba4feee7f6f176364093dec3f15a4d8aadc83fe1e28909b6ecd; + 4 43de563ee4818834fa190764e0aeda79811ff574b26466ac17415f3289d13715; + 32 42adb7c35588f8c6edb4abfc97b946a1649085165c7b8c3a; + 28 576eaa3954cc439e98263497d95da6b5e3d8279214f574c3; + 24 e28807d93e721c4ee87db0e382b7fd0ef97f7ea132915bb5; + 20 af22f7a7675fad35eb8782c40bd3c732cb1ed35c97654f8a; + 16 fe9d4746e3c184b1515a327e9e928c7a46b5a0cdb283baf9; + 12 9171f1fd2e0453fa5b993e99a6382068b0ca625dd3f9ac39; + 8 16823ab82ac0c840791945b5bce210ad634c57fe5c514cf5; + 4 bed515eaca34486fb2e069335c780d8e7b9b77c602696d9f; + 32 d79599b45b8f8293aaad48235eb95a2f; + 28 91442e4c2c8ae92f9dc870d7c3d6e0b8; + 24 da99ec771ce8684f4ca7ffa5df402ded; + 20 0d20204adc374fa840fa585a2d3a22cd; + 16 c3e2fb19d84accbbc5b715ea29ef175b; + 12 a3643da0859091dbe415fcad234bad6e; + 8 ab4292dc30d15a253e5a5360032cb3ab; + 4 74b7cfd2fc50a48ac5fad7c8d84a27bc; + 32 f53f5dd16d5986d94888a702; + 28 69bcdf722b40237c2e8fcd71; + 24 67e16b822be5718b363b3ff2; + 20 3d6fa2dabad3337e26a72bfc; + 16 389907e4b3cd3d0168d0a819; + 12 ff40fcbbbe7a203fc704dfcd; + 8 c67601e9b9f58b7a464e3f47; + 4 d1b2695277c7c8f8a9e9573c; + 32 238f3b1fc1fc218c; + 28 0f3657da64398b7e; + 24 07ffed4ca9d89a19; + 20 248ef8ba5dd3f022; + 16 b081c4be1451952f; + 12 c6932badc879fb36; + 8 5f41014f77919965; + 4 3d613ca8abe9c4ce; +} diff --git a/symm/t/safer b/symm/t/safer index 15f75ee9..cef5b9d4 100644 --- a/symm/t/safer +++ b/symm/t/safer @@ -11,3 +11,465 @@ safersk { 0102030405060708 0102030405060708 60d04ad7c49b8ded; 100f0e0d0c0b0a090807060504030201 0102030405060708 b260740f80d2445d; } + +safer-cmac { + bef260d7bcda163547d348b7551195e7 + "" + b9f9da8b0465e894; + 7022907dd1dff7dac5c9941d26d0c6eb + 14 + cf652451ff1ea9e1; + ad568f86edd1dc9268eeee533285a6ed + 810c9b689daaa9060d2d4b6003062365b0a54364c76c160f + 5056bba2984b1682; + 11896c4794846ecfa14a7130c9f13712 + 0634c9519848a877ff77bf79192a5b50ade5d9 + 2c9685d013b7efff; + cd739a3d1f337f29 + "" + b7c678291a02ea9e; + 549e6b0d27a4ba23 + 40 + 0cb9e87774a1ef4a; + 85406a6136512061 + f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + 0a9d5c038c99f36d; + 21635c6d62c92690 + 29df3e6057acc87638f508046733d9ff61cdbd + fe61dbd63946d430; +} + +safer-ccm { + bef260d7bcda163547d348b7551195e7 + 702290 + "" + "" + "" + 74955b21; + 7dd1dff7dac5c9941d26d0c6eb14ad56 + 8f86ed + d1 + "" + "" + 64c48de4; + dc9268eeee533285a6ed810c9b689daa + a9060d + "" + 2d + fe + a0c2fe72; + 4b6003062365b0a54364c76c160f1189 + 6c4794846e + cfa14a7130c9f137120634c9519848a877ff77bf79192a5b + 50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a + 0f78a0e09e9cf67419d6cec4139324f10d8b36dc7b0cc47a + 4495b1b7dac09ecb; + 6136512061f7080cc07df0591d8fa21f + 2dd88374d8 + cde8e160ad10997a21635c6d62c9269029df3e + 6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505 + d231d706e1a93d3f14c39ffb9b4e7d849e5daa713039d171cd99e50314 + 1b755d09c0126620; + da1435dceaa7b1cc + 49ae1d + "" + "" + "" + cd1b5bbc; + 50c38201a894476b + 3f102b + 75 + "" + "" + c2096bb2; + 2eb9529533966f27 + 043eb6 + "" + 21 + 53 + 25a20612; + b7f65b000961040e + f2f9b2fc5f + a450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3 + ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54 + 226b9bb081738ba5f6626653861db3f32832d8551f5a1b96 + 11e255d4c06111f5; + efc9a38378c5b93b + f4f2aad260 + 5faee2b03fb648e27fff63102758fe2b69ac26 + afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee + e06ad69863c7d36838a811277e746eb2319191c405682d38ccdff9654b + d3160250b4828281; +} + +safer-eax { + bef260d7bcda163547d348b7551195e7 + "" + "" + "" + "" + 75c1da0376977c83; + 7022907dd1dff7dac5c9941d26d0c6eb + 14 + "" + "" + "" + e8df12a3fceed9c1; + ad568f86edd1dc9268eeee533285a6ed + "" + 81 + "" + "" + 67fd181cddef533e; + 0c9b689daaa9060d2d4b6003062365b0 + "" + "" + a5 + 30 + b9ecf97c3093922d; + 4364c76c160f11896c4794846ecfa14a + 7130c9f137120634 + c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f + 29549e6b0d27a4ba234085406a6136512061f7080cc07df0 + fb58d0f5368ea912d10744647fe366bb418777601697e28c + 7ca11efe24763f77; + 591d8fa21f2dd88374d8cde8e160ad10 + 997a21635c6d62 + c9269029df3e6057acc87638f508046733d9ff + 61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c3 + 8f2eaca038f7cacc19b6cbd27ee094e6a78343fcead2b02356c41697ad + 216152ac7b8d453f; + 8201a894476b3f10 + "" + "" + "" + "" + b4d102bb91a06dbb; + 2b752eb952953396 + 6f + "" + "" + "" + ebaee4aba3e18cb1; + 27043eb621b7f65b + "" + 00 + "" + "" + 637a640605c9a7ff; + 0961040ef2f9b2fc + "" + "" + 5f + f8 + d5bfec2d60727408; + a450727a9b542cde + 52ebfda19d0ccc52 + 0f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090 + c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2 + 34969314934b38d9a462ef69cbbdb80c7cebd4e6361a5faa + 6f46339d37873473; + b03fb648e27fff63 + 102758fe2b69ac + 26afa3349829b94586306fed54154f8f28523c + 03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563 + 27ebc64f0dc6fea2eb465c16ddcf0fb51567e3a14eeccdcf37be2ffb0a + a925cad73bd83f84; +} + +safer-gcm { + bef260d7bcda163547d348b7551195e7 + "" + "" + "" + "" + 54d777d84bb367be; + 7022907dd1dff7dac5c9941d26d0c6eb + 14 + "" + "" + "" + ee0bd152340f8fa7; + ad568f86edd1dc9268eeee533285a6ed + "" + 81 + "" + "" + ef542fad7971981b; + 0c9b689daaa9060d2d4b6003062365b0 + "" + "" + a5 + 68 + 9775c4709ae7e478; + 4364c76c160f11896c4794846ecfa14a + 7130c9f137120634 + c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f + 29549e6b0d27a4ba234085406a6136512061f7080cc07df0 + ca09cf420396beb0c928209ae8423ebaf1230ae572f41b22 + 1f53984176941a39; + 591d8fa21f2dd88374d8cde8e160ad10 + 997a2163 + 5c6d62c9269029df3e6057 + acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7 + b71e6a6900bbf0745a3372bc9fb843931af8c9605701f49519b02c8c2649f8ed92 + bbc316814a9c8ff6; + b1cc49ae1d50c38201a894476b3f102b + 752eb952953396 + 6f27043eb621b7f65b000961040ef2f9b2fc5f + a450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6 + 12f78c86a8fe1b71db510309fe43a4434a5ff6a2c4dc3bc01f0feea936 + b3a2d8864a3eabb9; + c95a97a48030370c + "" + "" + "" + "" + f0d316bc4b69c200; + 33d090c54215abd6 + b3 + "" + "" + "" + 92be4864decdb6b0; + ad54efc9a38378c5 + "" + b9 + "" + "" + 7699b3ba70391bab; + 3bf4f2aad2605fae + "" + "" + e2 + 2f + 6826c1faff7a71a4; + b03fb648e27fff63 + 102758fe2b69ac26 + afa3349829b94586306fed54154f8f28523c03d4de160015 + 7846b710ee72807a2219bfb474fd71d891f24bb65d156325 + 9c27bc6e00c2e0ddb8d5e399439bf477cc02f23cca50e560 + d21750cf96e20752; + 9f9eb53b571ea629 + c54d57dd + 2d42f70800df9fcbaca48b + 77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040 + 76b11272cd887c5f6fa869e7bf52578442dd96e83b0e7cbcfdba46f67ba2ee6fc0 + 23f48c9f5534edbf; + a9b9a222bd689aef + 66f5306ceb0c6b + 08ac8b0a22260c571b4a42bb8fdb233bfa6a5c + fb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784 + cac8eef1be089b75a8ddb79ca8588436e6e9bac025a6d89bac100dc284 + d41ff215540bd48c; +} + +safer-ocb1 { + bef260d7bcda163547d348b7551195e7 + 7022907dd1dff7da + "" + "" + "" + e2e419f8cec4dcb3; + c5c9941d26d0c6eb14ad568f86edd1dc + 9268eeee533285a6 + ed + "" + "" + aba50e2dfc553b0e; + 810c9b689daaa9060d2d4b6003062365 + b0a54364c76c160f + "" + 11 + c4 + 4586e65f8c86dd50; + 896c4794846ecfa14a7130c9f1371206 + 34c9519848a877ff + "" + 77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4 + 07f19e04df183fe463e0f8d408918e4e90d5fa7c1fcbf997 + 8248b794a7bd1a4e; + ba234085406a6136512061f7080cc07d + f0591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c9269029df3e6057 + acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + 4f53021f22a68a8d47c855e163a27226b624dd712fab3e2a + ff7aaeba71e97e88; + 05e505da1435dceaa7b1cc49ae1d50c3 + 8201a894476b3f10 + "" + 2b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450 + 34d295b915f6715a7aac820be272519ed925b11bf0f86145df35751dae + 9f185db0d5f8cc21; + 727a9b542cde52ebfda19d0ccc520f21 + 5eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6 + b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff631027 + 2efe1a659d7d670d28fbe822b399e07290be6934f6cec51e8eb0362c7d + f9c31f6c694772d0; + 58fe2b69ac26afa3 + 349829b94586306f + "" + "" + "" + 88301767ee937c29; + ed54154f8f28523c + 03d4de1600157846 + b7 + "" + "" + e4b7676fbd808aa7; + 10ee72807a2219bf + b474fd71d891f24b + "" + b6 + a2 + fab55a01a7ce028e; + 5d1563259f9eb53b + 571ea629c54d57dd + "" + 2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb + b690481d25e3f847a804a19814c1290205ce9cbb4b61c233 + 87e5815156bfa03b; + 9fc2712a199e533f + a9156308cdec3f76 + 8281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22 + 260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb + dc2c2adba08e9ba7418ffc99171134a1581b124c03877cd1 + 220cc3fa8f48fdd3; + 3b6f5fe836813111 + 5c037ba323fe1dc8 + "" + 151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b + b8aefb9157f020717f5afd56802e8c489aa69a4ebbfd1a5c4e05ee4dca + 91762112616e9ad2; + 09c063c46f88de9f + d41e72d7b97e23e6 + eabdff3bcd211499268878dbf30f1dad89d4b9 + b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f08345 + 236430169ce67a46cf7a2b31e20aff1d656863550b2cbed9feb213bebd + 641bc761257b4572; +} + +safer-pmac1 { + bef260d7bcda163547d348b7551195e7 + "" + 061d742fa0b5e9fb; + 7022907dd1dff7dac5c9941d26d0c6eb + 14 + 496f756150b24f97; + ad568f86edd1dc9268eeee533285a6ed + 810c9b689daaa9060d2d4b6003062365b0a54364c76c160f + 659f6109ebea03e4; + 11896c4794846ecfa14a7130c9f13712 + 0634c9519848a877ff77bf79192a5b50ade5d9 + 169f91020e2bfa02; + cd739a3d1f337f29 + "" + bcb4bfd69665cfac; + 549e6b0d27a4ba23 + 40 + 1e041b274662fca9; + 85406a6136512061 + f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + 8b6e6d10707bb048; + 21635c6d62c92690 + 29df3e6057acc87638f508046733d9ff61cdbd + 8ca64eea215c495b; +} + +safer-ocb3 { + bef260d7bcda163547d348b7551195e7 + 7022907dd1df + "" + "" + "" + c68d1906e4ecf5b7; + f7dac5c9941d26d0c6eb14ad568f86ed + d1dc9268eeee + 53 + "" + "" + 3d2c6b8d272ad1bd; + 3285a6ed810c9b689daaa9060d2d4b60 + 03062365b0a5 + "" + 43 + 1e + ac7b2f4dcf701c36; + 64c76c160f11896c4794846ecfa14a71 + 30c9f1 + "" + 37120634c9519848a877ff77bf79192a5b50ade5d9cd739a + 3d77279a2b3174b4cda74767a200b3ced178c630f4021f95 + 46868129219846b1; + 3d1f337f29549e6b0d27a4ba23408540 + 6a61365120 + 61f7080cc07df0591d8fa21f2dd88374d8cde8e160ad1099 + 7a21635c6d62c9269029df3e6057acc87638f508046733d9 + 73f22628de757cf0ae4533014abe1e212cac8e7dc8d6c704 + b0592f0672c25ce4; + ff61cdbda3b3e9878731ebfedd4705e5 + 05da1435dcea + "" + a7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 14072ae825472e9f41b4d3608dcb28f76c38dba433fac5ac21885d3590 + 70c90062488d754e; + 21b7f65b000961040ef2f9b2fc5fa450 + 727a9b542cde + 52ebfda19d0ccc520f215eb57bb3a4f3ebbbb1 + 8ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93b + c67a74b2d9ab0e76d4e12ca3f67a21b36b96f6e153876245f24fb860d4 + da1bc80ce1be6ab3; + f4f2aad2605faee2 + b03fb648e27f + "" + "" + "" + 5c58fc2737aa84b2; + ff63102758fe2b69 + ac26afa33498 + 29 + "" + "" + 105063844d7b9bae; + b94586306fed5415 + 4f8f28523c03 + "" + d4 + 0a + bf73c757de4bdf7b; + de1600157846b710 + ee7280 + "" + 7a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea6 + 930c7d41a8b6f15ef14b066dc63cdddb1be6e934551bd1c1 + e40d324516b9b127; + 29c54d57dd2d42f7 + 0800df9fcb + aca48b77dba189196d1ebba10b0467cb9fc2712a199e533f + a9156308cdec3f768281e040a9b9a222bd689aef66f5306c + 1d2eb8f21e5e62392ffee6754fba853ce71e10ac506c9e4d + 57dec2089ee8cd44; + eb0c6b08ac8b0a22 + 260c571b4a42 + "" + bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037b + 1cd78bee247725a186a54ff71232b3197dbad5c69ea23db3dac003d3f6 + 3d21f3e8ffca5e4d; + a323fe1dc8151784 + 873f0eb5b647 + da6794c18b5337685a96ed65b9aca338527ef1 + 9b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878db + 59da4376f65bf4bfdf59cca15597d76b021a759e71d20b382f587e1a74 + ff7e706dfb3aadc7; +} + +safer-ocb3-mct { + 16 fcbfdf66d89efaa3; + 8 7acb5078112677aa; + 16 baa9bc81de93; + 8 ca467bdf7b39; + 16 f6659aeb; + 8 1b3348ec; +} diff --git a/symm/t/safersk b/symm/t/safersk index 8c42f586..59926349 100644 --- a/symm/t/safersk +++ b/symm/t/safersk @@ -1 +1,463 @@ -### No tests here. See `safer' instead. +### Only modes here. See `safersk' for the blockcipher test vectors. + +safersk-cmac { + bef260d7bcda163547d348b7551195e7 + "" + 9ba8f2c1b6cfeb77; + 7022907dd1dff7dac5c9941d26d0c6eb + 14 + 37dcfeffa9f5744b; + ad568f86edd1dc9268eeee533285a6ed + 810c9b689daaa9060d2d4b6003062365b0a54364c76c160f + 05bf5b261fbd88de; + 11896c4794846ecfa14a7130c9f13712 + 0634c9519848a877ff77bf79192a5b50ade5d9 + 0ee50cf1eb23cc77; + cd739a3d1f337f29 + "" + 975807086410e7e5; + 549e6b0d27a4ba23 + 40 + b5b26235e6a34f78; + 85406a6136512061 + f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + b98cae59f10f22cd; + 21635c6d62c92690 + 29df3e6057acc87638f508046733d9ff61cdbd + d85e3e89ce01118c; +} + +safersk-ccm { + bef260d7bcda163547d348b7551195e7 + 702290 + "" + "" + "" + 9a4a828c; + 7dd1dff7dac5c9941d26d0c6eb14ad56 + 8f86ed + d1 + "" + "" + 41f68f45; + dc9268eeee533285a6ed810c9b689daa + a9060d + "" + 2d + 7b + acc985bb; + 4b6003062365b0a54364c76c160f1189 + 6c4794846e + cfa14a7130c9f137120634c9519848a877ff77bf79192a5b + 50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a + aa629c01eb3b15ede6c2e4366419b5e5f40469d538d373ed + a136e047cf4a68b0; + 6136512061f7080cc07df0591d8fa21f + 2dd88374d8 + cde8e160ad10997a21635c6d62c9269029df3e + 6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505 + 1c34203b3161577c889c9db08bf34b20a3e5da5857a94d09e73edf7210 + 953f9c31334dfede; + da1435dceaa7b1cc + 49ae1d + "" + "" + "" + b5ad4f52; + 50c38201a894476b + 3f102b + 75 + "" + "" + f69a75fd; + 2eb9529533966f27 + 043eb6 + "" + 21 + 14 + 72b85363; + b7f65b000961040e + f2f9b2fc5f + a450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3 + ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54 + b65cbf23154b9798e5250e96f51659df1024bf6b0ffd859b + 9616166b0ae5320f; + efc9a38378c5b93b + f4f2aad260 + 5faee2b03fb648e27fff63102758fe2b69ac26 + afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee + 6d0ac961eed6fa2cad9f51d293bad02ecc7a8effe3511cb9aae4935bbd + 96dee0d7ba957d24; +} + +safersk-eax { + bef260d7bcda163547d348b7551195e7 + "" + "" + "" + "" + 9bc0cb5650ecbe0d; + 7022907dd1dff7dac5c9941d26d0c6eb + 14 + "" + "" + "" + 04655ac860f00c4c; + ad568f86edd1dc9268eeee533285a6ed + "" + 81 + "" + "" + 23de91600ff46611; + 0c9b689daaa9060d2d4b6003062365b0 + "" + "" + a5 + c2 + a47b7c287e2aaccb; + 4364c76c160f11896c4794846ecfa14a + 7130c9f137120634 + c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f + 29549e6b0d27a4ba234085406a6136512061f7080cc07df0 + d228821b771c225b34c32f1d8def6b1638a580259d14966c + c2d9f9bcacbf1796; + 591d8fa21f2dd88374d8cde8e160ad10 + 997a21635c6d62 + c9269029df3e6057acc87638f508046733d9ff + 61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c3 + 56e9c63e94a3e304fb0204a14ddce527063e43cbb59e5f4cdc5ca4c9fd + 3c18c6748c8d3efb; + 8201a894476b3f10 + "" + "" + "" + "" + a30a7f2fdcfd304f; + 2b752eb952953396 + 6f + "" + "" + "" + a3921ada1effe4a9; + 27043eb621b7f65b + "" + 00 + "" + "" + b21c194c92a0e99a; + 0961040ef2f9b2fc + "" + "" + 5f + 9a + ec1dc651cd6f903d; + a450727a9b542cde + 52ebfda19d0ccc52 + 0f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090 + c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2 + 74b140592d02d6e569a0f917fd935c2c4ff50e612a765163 + 69c737214ba7d4ef; + b03fb648e27fff63 + 102758fe2b69ac + 26afa3349829b94586306fed54154f8f28523c + 03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563 + bde1b3e1c19bb966ee531fa15ec929593e29aca538a004e1a98e6776f2 + ed2e0c47042a787f; +} + +safersk-gcm { + bef260d7bcda163547d348b7551195e7 + "" + "" + "" + "" + 27b0cf2d5823652b; + 7022907dd1dff7dac5c9941d26d0c6eb + 14 + "" + "" + "" + 284a84e5a061c638; + ad568f86edd1dc9268eeee533285a6ed + "" + 81 + "" + "" + e137081a8189b00d; + 0c9b689daaa9060d2d4b6003062365b0 + "" + "" + a5 + 07 + d1476d790c73fe20; + 4364c76c160f11896c4794846ecfa14a + 7130c9f137120634 + c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f + 29549e6b0d27a4ba234085406a6136512061f7080cc07df0 + 220e383555bc3c1db79dd7946ab1bcfb0c8ae7534e054dfe + b9125ab89a341129; + 591d8fa21f2dd88374d8cde8e160ad10 + 997a2163 + 5c6d62c9269029df3e6057 + acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7 + da40ac7ce7efbc6e5a0c8edad1fc6e37707dcd577c2b525173d91c0ee1843bf296 + 7fe1bd570ff9bc5e; + b1cc49ae1d50c38201a894476b3f102b + 752eb952953396 + 6f27043eb621b7f65b000961040ef2f9b2fc5f + a450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6 + 7088301eaa71ebd8aa7357fa70408eff7803127fdaf86f8f64fc46bde4 + 1b6b05d79e3e8a50; + c95a97a48030370c + "" + "" + "" + "" + c202c8435d5db9f9; + 33d090c54215abd6 + b3 + "" + "" + "" + 127f007760bb2caa; + ad54efc9a38378c5 + "" + b9 + "" + "" + 8e7eb7606063486c; + 3bf4f2aad2605fae + "" + "" + e2 + 87 + f7db784dd6349ec3; + b03fb648e27fff63 + 102758fe2b69ac26 + afa3349829b94586306fed54154f8f28523c03d4de160015 + 7846b710ee72807a2219bfb474fd71d891f24bb65d156325 + e9a1e4e745d37146bd75efe05e451dbf120fe907a9f5701f + 59283c69e487ac87; + 9f9eb53b571ea629 + c54d57dd + 2d42f70800df9fcbaca48b + 77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040 + 65b78f763a328655662a4ef7f9bacfe67e5e07df80edbcc853440ee1f7627d0355 + 38dbad9c5138e19e; + a9b9a222bd689aef + 66f5306ceb0c6b + 08ac8b0a22260c571b4a42bb8fdb233bfa6a5c + fb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784 + 0d4082f666ad6a4d337a93564bc648f4b09e2332d656aeebefd722a7ec + 4322ea279fd752dc; +} + +safersk-ocb1 { + bef260d7bcda163547d348b7551195e7 + 7022907dd1dff7da + "" + "" + "" + 02524b8ee7329780; + c5c9941d26d0c6eb14ad568f86edd1dc + 9268eeee533285a6 + ed + "" + "" + aa1f6928e1b81e20; + 810c9b689daaa9060d2d4b6003062365 + b0a54364c76c160f + "" + 11 + 07 + cc863f9f86e79df5; + 896c4794846ecfa14a7130c9f1371206 + 34c9519848a877ff + "" + 77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4 + 0a622ec626cf3be0c96a8fcabfa824949c81cf57656e3fcc + 4b897d5463f508df; + ba234085406a6136512061f7080cc07d + f0591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c9269029df3e6057 + acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + ceaa0608044abe172e762b8a66a026b6aa231a60e32b8852 + 383b6f426f78e95d; + 05e505da1435dceaa7b1cc49ae1d50c3 + 8201a894476b3f10 + "" + 2b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450 + e9d6111a98647e1da68ba0bdfb386b3575c20aba3fff9bb7d5e52e5717 + f432ded708b7e826; + 727a9b542cde52ebfda19d0ccc520f21 + 5eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6 + b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff631027 + 58a7612db1435cc3b8b7ab586fd3475674faa6192c47cf940061b38ad0 + ee64360a85eb7957; + 58fe2b69ac26afa3 + 349829b94586306f + "" + "" + "" + bffcea16dd9830d2; + ed54154f8f28523c + 03d4de1600157846 + b7 + "" + "" + 9d9d3268ed1e6af0; + 10ee72807a2219bf + b474fd71d891f24b + "" + b6 + 55 + 7cc85e98d653ac98; + 5d1563259f9eb53b + 571ea629c54d57dd + "" + 2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb + 69fd708caa761fa04396ba9f94bb916e5a11679b3bad9cf0 + 8c94cf5b2249afa6; + 9fc2712a199e533f + a9156308cdec3f76 + 8281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22 + 260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb + c9e3275788dcac045ae1478a44aac8061f02bc7e56e516cc + 8adfde6b3cd647c5; + 3b6f5fe836813111 + 5c037ba323fe1dc8 + "" + 151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b + f1493455c6ef6dfb73ba4b35b25ecef1d967614169fd0db3162575f20c + 533087817a013891; + 09c063c46f88de9f + d41e72d7b97e23e6 + eabdff3bcd211499268878dbf30f1dad89d4b9 + b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f08345 + f89081f88fa58ddd7f1974ffc3fb676fc8855e74c7b85d6e308e2c3096 + b0c2845962f040ff; +} + +safersk-pmac1 { + bef260d7bcda163547d348b7551195e7 + "" + 6dd75ab7922413b1; + 7022907dd1dff7dac5c9941d26d0c6eb + 14 + 7f4d03871ad27bda; + ad568f86edd1dc9268eeee533285a6ed + 810c9b689daaa9060d2d4b6003062365b0a54364c76c160f + 3f48cfbe20527417; + 11896c4794846ecfa14a7130c9f13712 + 0634c9519848a877ff77bf79192a5b50ade5d9 + 25fb410e71c6553d; + cd739a3d1f337f29 + "" + af55847d75152f93; + 549e6b0d27a4ba23 + 40 + b24dc9bbdbe4b417; + 85406a6136512061 + f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + 9e119f41d7bf7b13; + 21635c6d62c92690 + 29df3e6057acc87638f508046733d9ff61cdbd + 9f8f71cddf2bf6dd; +} + +safersk-ocb3 { + bef260d7bcda163547d348b7551195e7 + 7022907dd1df + "" + "" + "" + 6e456312a40d6780; + f7dac5c9941d26d0c6eb14ad568f86ed + d1dc9268eeee + 53 + "" + "" + 65b5cb090a3f28ae; + 3285a6ed810c9b689daaa9060d2d4b60 + 03062365b0a5 + "" + 43 + 63 + 4e6dc1b24486771b; + 64c76c160f11896c4794846ecfa14a71 + 30c9f1 + "" + 37120634c9519848a877ff77bf79192a5b50ade5d9cd739a + fa8d42d4d17056a5cb34c6792272af358e3c7e7b9490aa3f + 3acb963aa0fc701f; + 3d1f337f29549e6b0d27a4ba23408540 + 6a61365120 + 61f7080cc07df0591d8fa21f2dd88374d8cde8e160ad1099 + 7a21635c6d62c9269029df3e6057acc87638f508046733d9 + 8cd70cce2aaf4a9ea62faa31d7146087d2b9b47e7992e17e + 3e16cf32a2faa211; + ff61cdbda3b3e9878731ebfedd4705e5 + 05da1435dcea + "" + a7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 239d7c4c0f2c17577768de8cbedf192d08e82cfc74a587ab5267ee7e81 + e6f7aad35cceb122; + 21b7f65b000961040ef2f9b2fc5fa450 + 727a9b542cde + 52ebfda19d0ccc520f215eb57bb3a4f3ebbbb1 + 8ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93b + bbd3b140decdd5e0a63b4a38989e770bedbe26054f882cbf1920fbd514 + a71d070227d87267; + f4f2aad2605faee2 + b03fb648e27f + "" + "" + "" + 63e4d0211e0a4daf; + ff63102758fe2b69 + ac26afa33498 + 29 + "" + "" + 0fb3f4a5cc43406a; + b94586306fed5415 + 4f8f28523c03 + "" + d4 + 06 + afaa82d25e44d4db; + de1600157846b710 + ee7280 + "" + 7a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea6 + bc640b0230973b8be088cdc0f0c18fafe95f13d3197d9c09 + e42c5b6c0e33d57e; + 29c54d57dd2d42f7 + 0800df9fcb + aca48b77dba189196d1ebba10b0467cb9fc2712a199e533f + a9156308cdec3f768281e040a9b9a222bd689aef66f5306c + f9f9760a9b9277c4216a7d12c59d78f7cfc3c5fe811f9e38 + 26bd0ba14ccc28d3; + eb0c6b08ac8b0a22 + 260c571b4a42 + "" + bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037b + 35511a69e4039fa87bf9cccdd152453842004258de53166380645f0c57 + 99979d46633f3381; + a323fe1dc8151784 + 873f0eb5b647 + da6794c18b5337685a96ed65b9aca338527ef1 + 9b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878db + b6190f6df6109cb3134a517871e360503ace233210255bd503451ccf78 + b9d9982e2ad6564b; +} + +safersk-ocb3-mct { + 16 3857e95d746bbe01; + 8 545057df78fb5ea9; + 16 c2e0438d09ff; + 8 36b5c340bd6d; + 16 5dee93a9; + 8 8752f8e9; +} diff --git a/symm/t/salsa20.local b/symm/t/salsa20.local index 91887492..b03d2c3a 100644 --- a/symm/t/salsa20.local +++ b/symm/t/salsa20.local @@ -87,3 +87,15 @@ xsalsa20 { be075fc53c81f2d5cf141316ebeb0c7b5228c52a4c62cbd44b66849b64244ffce5ecbaaf33bd751a1ac728d45e6c61296cdc3c01233561f41db66cce314adb310e3be8250c46f06dceea3a7fa1348057e2f6556ad6b1318a024a838f21af1fde048977eb48f59ffd4924ca1c60902e52f0a089bc76897040e082f937763848645e0705 8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186ac0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da99832b61ca01b6de56244a9e88d5f9b37973f622a43d14a6599b1f654cb45a74e355a5; } + +salsa20-naclbox { + ## Taken from Daniel J. Bernstein, `Cryptography in NaCl', + ## https://cr.yp.to/highspeed/naclcrypto-20090310.pdf + + 1b27556473e985d462cd51197a9a46c76009549eac6474f206c4ee0844f68389 + 69696ee955b62b73cd62bda875fc73d68219e0036b7a0b37 + "" + be075fc53c81f2d5cf141316ebeb0c7b5228c52a4c62cbd44b66849b64244ffce5ecbaaf33bd751a1ac728d45e6c61296cdc3c01233561f41db66cce314adb310e3be8250c46f06dceea3a7fa1348057e2f6556ad6b1318a024a838f21af1fde048977eb48f59ffd4924ca1c60902e52f0a089bc76897040e082f937763848645e0705 + 8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186ac0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da99832b61ca01b6de56244a9e88d5f9b37973f622a43d14a6599b1f654cb45a74e355a5 + f3ffc7703f9400e52a7dfb4b3d3305d9; +} diff --git a/symm/t/serpent.local b/symm/t/serpent.local new file mode 100644 index 00000000..d7a0340f --- /dev/null +++ b/symm/t/serpent.local @@ -0,0 +1,992 @@ +### Local tests for Serpent. + +serpent-cmac { + 60d7bcda163547d348b7551195 + "" + 837d499a07a2518f04835f42131f5831; + e77022907dd1dff7dac5c9941d + 26 + db320e0bfa3ebb37c57ea0c60576c393; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1371206 + 0c9a89126f4cad2192ffa4a7c0ca9d68; + 34c9519848a877ff77bf79192a + 5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8 + 324c00f44175151d1a2bf9342cf4ef93; + 8374d8cde8e160ad10997a21 + "" + 829328f2a128fdc7c48a7714a5f66acf; + 635c6d62c9269029df3e6057 + ac + 28d493c79ae17e3c1480c921bf4e6d2e; + c87638f508046733d9ff61cd + bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 63c9c5f2dcd9e476c72dee514b84d6f9; + 21b7f65b000961040ef2f9b2 + fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5 + ca4332a12b4981383e8548d4beacce63; + 4215abd6b3ad54ef + "" + 51a036a675d7fd48aea66b5fea454712; + c9a38378c5b93bf4 + f2 + 5b8642963edfd3fc3537cf7a53ffdb72; + aad2605faee2b03f + b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219 + 40bbb9860714b5c28a127928704b04f2; + bfb474fd71d891f2 + 4bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9f + b59d4d54d7846d564c8e65a6ae652a74; + c2712a199e533fa9156308cdec3f768281 + "" + 9af557733264840dca5e8260f160ffb4; + e040a9b9a222bd689aef66f5306ceb0c6b + 08 + ca7d2919e279fd3caf61e6ff35bb7803; + ac8b0a22260c571b4a42bb8fdb233bfa6a + 5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65 + 33036f52f479780af315c2de95e9dc86; + b9aca338527ef19b09c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d + 8ef0d030ddb7bd4c700e15efc563f5cf; +} + +serpent-ccm { + 60d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9 + "" + "" + "" + dc912161; + 941d26d0c6eb14ad568f86edd1 + dc9268eeee533285a6ed81 + 0c + "" + "" + 5499b369; + 9b689daaa9060d2d4b60030623 + 65b0a54364c76c160f1189 + "" + 6c + 52 + ea1be4b3; + 4794846ecfa14a7130c9f13712 + 0634c9519848a877ff + 77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + 1d58fa7d358e6d619c942eb0285e79dbce0aee4e671ef19021d80ece2710a144ae511c8f973ff2f06d8c6f0cc2942c5e + 18d3a010e72c36fd75d6c2379c947385; + 05e505da1435dceaa7b1cc49ae + 1d50c38201a894476b + 3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0c + cc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb6 + 7b48d588bb1af8f0eff0e80c692d51010b7f3b1d6655b2e18c1241862819d1a25631053d5eea17417a5b5c928d32eb181043df7dde + 8e0224854ea7153f52e096633776fc97; + 48e27fff63102758fe2b69ac + 26afa3349829b94586306f + "" + "" + "" + 940a7ecd; + ed54154f8f28523c03d4de16 + 00157846b710ee72807a22 + 19 + "" + "" + 99081a6e; + bfb474fd71d891f24bb65d15 + 63259f9eb53b571ea629c5 + "" + 4d + 95 + 67001f0c; + 57dd2d42f70800df9fcbaca4 + 8b77dba189196d1ebb + a10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c57 + 1b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da67 + 59c14232f48220ad1f3966d9d52d9b9b9ae739c4fa6a690c445716eb73951b229de71b78e83b03ac3401f58adaafd1bd + 2f3304e936c26f3998308ceb36022d3a; + 94c18b5337685a96ed65b9ac + a338527ef19b09c063 + c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e + 7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d079839180 + 99574f4879d83e020a18b5133a5c97d0c7fc72a37e787d16e6d8e959df0cc8d9b62cb8f54d74208c140f13abce1dc058829dc0bd01 + 0dd232275c64fcfc8b5d0fc2bf948ebe; + 5da08da3aefc5f85 + 84b7c5e617669c0f16e398 + "" + "" + "" + e6725fe0; + 15d4e9cfce3ed1ec + df3d264a7f16cb16c2e815 + f4 + "" + "" + ad7b2fe0; + 22cdf0c8e30308be + 3c31e6bc58c0b7cadcb658 + "" + b9 + 6e + f2943ec1; + 70e47479a684b5ae + fa69a4cd52147ed12c + a986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae98 + 5511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608 + e1e63326b5795e04360ba24658defb1216302976c9a921ea18adf8b1723a91a6a8095e1d2b49a9e48cd603dd707d881e + 1b69dccc1f344f1ca9d04a725b5481bc; + fe95e81c2533e31c + 9c1a9851bc2810d858 + cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a7 + 7456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0c + 61ad6fd5019e1229ae86cd9840357861473a647ec3a939e9e68113c289e1f917e658651cf2217aa46837c404632b1feabb16939df0 + 6881e216ee5fd2da76529e9019027188; + ae9ce021a5f1fa4ffa91544485f1a1258b + 2b9b8f0911e32d65cc1770 + "" + "" + "" + 6679e4e9; + a18cbfe6effd1ff6778554acf1270485b2 + 03a3c1c4c967c0a458cb94 + 8b + "" + "" + c6460f74; + dd409b687fa3a6827b480aa3a4c84cef64 + f6c9b53bf8f957f4b03cf4 + "" + 3e + 83 + b85403e7; + 89957f9a3e8128f8743d16687b7bb8deb9 + bd205b70e04c091d20 + 5cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397 + abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107 + 2651fec0d8fcff49d1f5df59bf41bd0c6fef0e7d49c915bd20f775ffd8af47be58f20ed9f7a5709978e5af892ff52ea6 + 8247a18e44f3a38840a6c98db85a10e3; + c8e7d715a92add9589d1f5c054b2d98351 + 4605ec590294a319b9 + 802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee + 1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44 + f060d6a432737be40681731d964ae4310460967fab931db70fd394d02c4f2691b14891986837af0342d9d01e688498e161ce84598a + 6db772689af25f8ebba8ad1966dfa1ea; +} + +serpent-eax { + ## Taken from Secnet, with thanks to Ian Jackson. + + 233952dee4d5ed5f9b9c6d6ff80ff478 + 62ec67f9c3a4a407fcb2a8c49031a8b3 + 6bfb914fd07eae6b + "" + "" + 1271ec1e68330eb461a96d3a3a7a2707; + 91945d3f4dcbee0bf45ef52255f095a4 + becaf043b0a23d843194ba972c66debd + fa3bfd4806eb53fa + f7fb + 1c73 + 67d3db493a1f7b054ececa2a2cf37ee6; + 01f74ad64077f2e704c0f60ada3dd523 + 70c3db4f0d26368400a10ed05d2bff5e + 234a3463c1264ac6 + 1a47cb4933 + 2439712b59 + b13982351ba05b25bb2bd3b95df62d73; + d07cf6cbb7f313bdde66b727afd3c5e8 + 8408dfff3c1a2b1292dc199e46b7d617 + 33cce2eabff5a79d + 481c9e39b1 + f1d718884b + e94b29e143a264b54e283ca9e439c90d; + 35b6d0580005bbc12b0587124557d2c2 + fdb6b06676eedc5c61d74276e1f8e816 + aeb96eaebe2970e9 + 40d0c07da5e4 + 5936db85df31 + 199ba3556a5d5eff1964a6befea0d950; + bd8e6e11475e60b268784c38c62feb22 + 6eac5c93072d8e8513f750935e46da1b + d4482d1ca78dce0f + 4de3b35c3fc039245bd1fb7d + 7a3a7997ee349b57152cc43f + 723903a85b09d86456315ac0d9180724; + 7c77d6e813bed5ac98baa417477a2e7d + 1a8c98dcd73d38393b2bf1569deefc19 + 65d2017990d62528 + 8b0a79306c9ce7ed99dae4f87f8dd61636 + 73548ffaf45d2617eb25ad1dffa1842083 + 6d48394d5ef2cd2e0e30cdd2f4c52d96; + 5fff20cafab119ca2fc73549e20f5b0d + dde59b97d722156d4d9aff2bc7559826 + 54b9f04e6a09189a + 1bda122bce8a8dbaf1877d962b8592dd2d56 + e8bd1c6fe47df149a141ce813b0c1239542e + c4cbf7b3968388d631e6f4ffe86e14e7; + a4a4782bcffd3ec5e7ef6d8c34a56123 + b781fcf2f75fa5a8de97a9ca48e522ec + 899a175897561d7e + 6cf36720872b8513f6eab1a8a44438d5ef11 + e4a9d72847d437b85f10b7daa46f1e00e350 + 9af0b97961c39dfbb70170b6c4cadbc1; + 8395fcf1e95bebd697bd010bc766aac3 + 22e7add93cfc6393c57ec0b3c17d6b44 + 126735fcc320d25a + ca40d7446e545ffaed3bd12a740a659ffbbb3ceab7 + 83d69403eae9386b679daeaad2951465f8ddf9be1a + ffad1c5fef072f8b48bd58c07fee3d83; + + ## Locally-generated tests for edge-cases. + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + 47f4f974dac8fbccb2d85c4dd030ecc2; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + fdd1a67df6ef4962c0e07c3bcb258fdb; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + dddced0e626e1a606ad6150f981231c4; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + 93 + 994b5c972bc7d85771220863405b62be; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794846ecfa14a7130c9 + f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7 + 080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61 + 82f5aab367d2f92bb06cdbdcf3b840fa03775f8473bc2c7923d06b0d264679c2bb8ad3a0b4008946198caa858ac3035b + 4be2dd26de2bb142d08d2e80ff7e1556; + cdbda3b3e9878731ebfedd4705 + e505da1435dceaa7b1cc49ae1d50c3 + 8201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde + 52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260 + 4a2f0f21a4c240fcebbda1500c1c87193c1100ab9922b6c02b6200eb6c4c166ba715f09ba95ff7daa0a49a92139b1fb7785198c3cd + 7597b3928b3811ad02ba9c380fc053b7; + 5faee2b03fb648e27fff6310 + "" + "" + "" + "" + 0a85bbdf824c6fd51bb56934219a44bb; + 2758fe2b69ac26afa3349829 + b9 + "" + "" + "" + 8b3c4c5ef77b2b25cd78f8e7ee1a1eeb; + 4586306fed54154f8f28523c + "" + 03 + "" + "" + 9dd8b376a786caa020f631ec33e8adee; + d4de1600157846b710ee7280 + "" + "" + 7a + 9d + 66d221c6542adab014cde389a8375271; + 2219bfb474fd71d891f24bb6 + 5d1563259f9eb53b571ea629c54d57dd + 2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222 + bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe836813111 + d70c3fe1525edf6975dd3ec110f44d66ee38812bee278632cd476e9571d90ea3a4181e472841e699acbb613172b3c8d9 + cf949b9623f6027249246ff3914f4c9e; + 5c037ba323fe1dc815178487 + 3f0eb5b647da6794c18b5337685a96 + ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89 + d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d + bbeb0d455e42b31743e6b1f62e7a8beb05b6579140f9523b441f1523fffd56799ea74a815f64cd65fe2d912c0ac88a42d668020ad4 + aa19b7bc58fb57f2cd072ed13f7a22d1; + 30ce2f1fef6ef315 + "" + "" + "" + "" + e071f4b5be472b5d27a62d3b59de4076; + d0798391805da08d + a3 + "" + "" + "" + 9700bb529c726f7f9383103afde5c072; + aefc5f8584b7c5e6 + "" + 17 + "" + "" + beddb35cd6ce26eeccd01fc49467f581; + 669c0f16e39815d4 + "" + "" + e9 + 89 + a6ea652052db22889858bba51b743f77; + cfce3ed1ecdf3d26 + 4a7f16cb16c2e815f422cdf0c8e30308 + be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98 + ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b009 + c343474bde0f534fb167d4f0f45dc029376218f83a54b3dd22eaf08ceb381357ae3c3f73e48d26775bbb3d09ea1300c2 + 9184a5120a75b987ebf1c111ee0f7fe0; + 51f284649016ed00 + 456331854bc78bf43966eb0cfa9138 + ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb82 + 4173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc5 + 8a5f8d241fd8edabb3447134fced691a560ffc16eb35351f299055d61c65a9d016a8a2aecd321e2aaba5be088bc4e787d23279d3b9 + 2d94ce868ac29109422a40835e92df30; + 97f56ccbb2f294b38766fc69f6a9f2c094 + "" + "" + "" + "" + cc3b89f1e518665f325656d16078b115; + 5ffd505003cc0cae9ce021a5f1fa4ffa91 + 54 + "" + "" + "" + 77f9efcf277f9618606fd47f5233bb79; + 4485f1a1258b2b9b8f0911e32d65cc1770 + "" + a1 + "" + "" + 4d91889c474511f47711a00d22a37021; + 8cbfe6effd1ff6778554acf1270485b203 + "" + "" + a3 + f2 + db79e93136fbbcb2d167a14005e3e4f4; + c1c4c967c0a458cb948bdd409b687fa3a6 + 827b480aa3a4c84cef64f6c9b53bf8f9 + 57f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac + 8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef340153 + 242f387588ee5c723abeac99f710a02c29c5d9420475d5c81cd7840cdb9c965b2357c9fd6cf4ed18247daf5e5b4908d6 + 72aa25cd54aa0ed7bb78fdf9d491547e; + 9c51d2a90bbf7f1bfc338ab0ef5746ea8f + dcccd213e33f7e8a5718fd25014107 + c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7 + ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7ab + 2ea09fe497954fcc5ff649f0c72b229294018f6d69846e4d55b35fcf561d6d73e36fd253241af102f1a5beabca9f878898bebc3c38 + 018ad589b2a12c05238a52773fd66463; +} + +serpent-gcm { + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + b7a5e3afee9d6b5d3272a42db95fe058; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + 5a3f93b2c28c3208f3f470a28ded0981; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + 31b6ec116273e033816b5ebeb8198b1c; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + 82 + 1edf5ba454a8cd5ef0aac6153800a101; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794846ecfa14a7130c9 + f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7 + 080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61 + 08276a3d1fd2638903bb85fd5ad5b3abf64d1e384ad5262501e198e697c210d778ef1ca2cb78e3fc462d18daaba7ee12 + 75eb776d709e756036210b8d85056fdd; + cdbda3b3e9878731ebfedd4705 + e505da1435dceaa7b1cc49ae + 1d50c38201a894476b3f102b752eb952953396 + 6f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33 + 6cf5fafa1f1b67aef17c51ecd4cc8807863bb47816d9416eee45e144973c6bfe325b1dd7b29af06a4d9b0e2f993127dcbf33e8075f35781fe7 + 8827e78f2a8ba21a12f6c4078713d83b; + d090c54215abd6b3ad54efc9a3 + 8378c5b93bf4f2aad2605faee2b03f + b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee + 72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b04 + 11687e1abefb35846b4c37d820220610a076a589e33bdc58b8b9f4f5318a945421139b3122e26578e3d34e00ab2cb88a0de1590b46 + 75d611a4d23fc1cc399cb1d06475c400; + 67cb9fc2712a199e533fa915 + "" + "" + "" + "" + 2e79ef91df0515538a3bf641867668d4; + 6308cdec3f768281e040a9b9 + a2 + "" + "" + "" + 4a3d8a26dac3498e97ec445243d6073f; + 22bd689aef66f5306ceb0c6b + "" + 08 + "" + "" + c47eae4dc6e8e34fd594bcf425c93137; + ac8b0a22260c571b4a42bb8f + "" + "" + db + 08 + d328c14d09ea87f05101640b5c19ec06; + 233bfa6a5cfb0bad7d95214a + de49cb3b6f5fe8368131115c037ba323 + fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6 + eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f08345 + 681e86e5aebd4a9648b78daa6bc86d34de3970fa7065f26789d65cb8d0d05639849b612fef76214315948d44f3e9c512 + 2a4f1ff8cc104ded9d693f28d62396a3; + 5b663e4ee1315f3c8f2aebfa + 921451dcd1af5813b70d30ce + 2f1fef6ef315d0798391805da08da3aefc5f85 + 84b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684 + cbd8037fa6cca0d3c5d760f9775d6ec6b3349a80089425f3a72f47fa138d41ddb7d165fdf2df4d5ea97d430b173363a87cf9d61ef829127ba7 + f2f7d0abeac736dbcb17c8b11a614ef5; + b5aefa69a4cd52147ed12ca9 + 86981a874498ad0abef8bc4fcb70e2 + 7e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720ee + f9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d8 + 78aad8dbb0a294e0d23f61421d9adf39e537651cf5d91bc9e815307a021e916467f1abae1cf7eb09aadf42f053f6c9dbb099b7587c + f40974b1334cf4c25e29bc26f608bf94; + 58cbbc8424d126b8 + "" + "" + "" + "" + 65a882a10602424ef433579558fd91db; + 07e6daa089c3f909 + 9c + "" + "" + "" + 67a19a1d408be278d46cb09c2d09e5ca; + 5ffb824173d7634c + "" + 04 + "" + "" + af4590dab6b84c9ab769597a6075bb40; + 226f30cbb7f0e4a9 + "" + "" + 73 + 19 + ee176a9eb69f35199805f8c19b5061bb; + a8cd190107314717 + a77456f3ff669c732b58db8f48af65f7 + cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91 + 544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd + bcece9311f7669d6f744b547aafeba06c7cb05e623325f183ec1c0b24424f612b10a539f684fd1c0730ee75e5deb2b55 + d6c09aed972bfb56ab024c80fa114965; + 409b687fa3a6827b + 480aa3a4c84cef64f6c9b53b + f8f957f4b03cf43e89957f9a3e8128f8743d16 + 687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2eccc + fd90ce8763bd7ad21f288077677eb3cfee48137ffe89d5c5965b3d99592896c4eb94b6573c1610d266609da17e3192a833bddc1a656e91b4f0 + 87a7ea3dc29335c676a2d8453d5232ec; + b44d65bad397abfa + f529ee41cf9a05c7efedef3401539c + 51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c0 + 54b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe + d29ece81f1d8523540fd3e4edae0f717730b301f05f3c9fae128581349a2740ae49266ed8d83a2216072ed232e280163b9531f80c1 + 9f123aa15e25f65aeda0a8c05855c696; + 079753ee1a957eb6d6699e6b7ea2725cb2 + "" + "" + "" + "" + 0d19fefb39f9d5ca47305f578da4c2a6; + dac07ecde95759ac46fee6dda7abc8ad68 + da + "" + "" + "" + 33e9c876994b5d473cee7028bd8bc422; + ac90cfe22d2f1f2968cc42fa8b669ed3bb + "" + 35 + "" + "" + b5f2eefdbd65dad3c85637c4644d81b8; + 42a9cf44bbc8c6254d980398bd94e66eb4 + "" + "" + 56 + a1 + 41f9c05ae9ec028487faba6297d754aa; + 3d405e51881e99027b8ab9aea3ccf860b0 + 009740763d96836c5f87b95460938de1 + 288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c3680 + 0d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f + 62a4e874b9bed58dfa604492bb7d314c941a359fb4704211a03bb5efb5bd1ead5f4bc209c9ed2ec55945e542da07de30 + 9ab10e04cce4cdb21816a452838e207e; + 834a06148f302c3973accd56f6f24e3395 + 8b8c2e2352fd61e4fa8fec81 + 6ac861a8b33779f09e7a10fc02a8f48afa3080 + ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fd + 6be1ebdac5a498d5c1005189710616d5317726377ccdde02d771a44d9127704c821f1056a1079d34e742ebfdfd11ef3aea46b18655bb2ffe88 + fd98fa8d62a384d07a991fb3caea3398; + e2893232a9f81d14517ffae475f6b94a43 + a67b3d380d2f9aaafe2dd721c0095c + 8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785f + e426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a + 100ee38a4070af0c2e7ea43836fcfa78a65278a09ab122bdcdba11d93b63c2965341b19ff4be55ced558fa76d5c3fcb0227e037572 + cec6a5923cedad5ad0bc6551a039ed2d; +} + +serpent-ocb1 { + 60d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9941d26d0c6 + "" + "" + "" + 686b0aac51a25d6f2878b1e50e2badbe; + eb14ad568f86edd1dc9268eeee + 533285a6ed810c9b689daaa9060d2d4b + 60 + "" + "" + 2811539055c7b5c0e10cabfd66d63d09; + 03062365b0a54364c76c160f11 + 896c4794846ecfa14a7130c9f1371206 + "" + 34 + b7 + 736d9cb5d0427f0eea7a387136323745; + c9519848a877ff77bf79192a5b + 50ade5d9cd739a3d1f337f29549e6b0d + "" + 27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e + c3b13eaa510c580acba8cba253b30f944b369f12002ddefee96ff13f3e7daa0e9836f355b08a055f75839883f3ae65a3 + 81f7d94ad9ffd90dbfaef2d3643f1470; + 6057acc87638f508046733d9ff + 61cdbda3b3e9878731ebfedd4705e505 + da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5f + a450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54 + 6f6ee0f2bfb91b2eaafde0609efb27f9df091d396cc5932c67c3989439a21fd0528a27da02e746de3bd96e6692f8bfc8 + 05aeefe7a4a38c082ec19f1ab2404541; + efc9a38378c5b93bf4f2aad260 + 5faee2b03fb648e27fff63102758fe2b + "" + 69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9e + 2fa135d2df5aa9ed43e094bba67d692edefd217d7d8f2c64a0f8a2c728176ddd7e699e8ff6681e2508ab05b1014bf461fc21d13f14 + ba576b55bfc099c9cf4db5c28e90b761; + b53b571ea629c54d57dd2d42f7 + 0800df9fcbaca48b77dba189196d1ebb + a10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b + 0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da67 + ee27f377eff38f2464b289b25dee0a73b9a803fbf821ec328a488dce759e240625a7b3103d49c590858da2771988d0c66c21f12884 + 54ef913069c3dd1c9685f2472b7fc3f4; + 94c18b5337685a96ed65b9ac + a338527ef19b09c063c46f88de9fd41e + "" + "" + "" + c4b88fee21ecbc1ffbf6ea083a080716; + 72d7b97e23e6eabdff3bcd21 + 1499268878dbf30f1dad89d4b9b12012 + e4 + "" + "" + 8e5107d4d70c8a727e44b79fbce267ef; + 713df46795630e7952d22bb0 + 2d7100b8b649377d20a8f083455b663e + "" + 4e + f2 + fade84801d77de290eb960862c98d943; + e1315f3c8f2aebfa921451dc + d1af5813b70d30ce2f1fef6ef315d079 + "" + 8391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e303 + 48a4a77a5651db3c1dd8baae2ce157c1411d1e70c22826da41446890d00ef14467c0439f1f0d10ed95ab8ee0f624f64c + d2c05303138ae9ec11f3320c4a9fc1fa; + 08be3c31e6bc58c0b7cadcb6 + 58b970e47479a684b5aefa69a4cd5214 + 7ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9 + f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908 + 402444f7ccf9e0aa13173b33afe0bb1e38c233ade7ff56f92a24bd8d17cb137ad49475b39cf3c34a56d074faa7449405 + 67924f31b67c3fc19ed79b5df55e286a; + 445608fe95e81c2533e31c9c + 1a9851bc2810d858cbbc8424d126b807 + "" + e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3f + 5fee9263e96affb3166ef4f393ad28c9baac39c0bcd021025d930e9c4ae105ed386f4664d28857b8d29c83f377590385c8252bbbac + 3ec53f10d421ae13299f734e4c33c5c4; + b90e1721b730374ffc9bc597 + f56ccbb2f294b38766fc69f6a9f2c094 + 5ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6 + 778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f + 613d48844e3ff8fd0fa43fe6356b519c8e851d8b70f90d4bbb82905ac14e77e4ce53fb727b8c408bda29425856f06d722308628b27 + 2e3f1daa8e87557852dbb4d5a9f0e978; + 9a3e8128f8743d16 + 687b7bb8deb9bd205b70e04c091d205c + "" + "" + "" + 595360839f7632d4470fad88b88bcb17; + dad9e9a79b1abf91 + b0851e5ca605ac845139958701167750 + 8a + "" + "" + 446bce84dfdd94177e90e9bae6bfc1c5; + 15dde524af3e2bee + 0646541a42c2ecccb44d65bad397abfa + "" + f5 + d6 + 1c8be9521e25a947fb8bcea3f3e095cb; + 29ee41cf9a05c7ef + edef3401539c51d2a90bbf7f1bfc338a + "" + b0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b980 + 3f68fd5d2677fb15a8c99b65baf1e8aedb5a71b8756fd5326567128473762ae4498809325d9f2d1a031e58b9f181266f + 723cde60d1e536a1e076650f3261f473; + 2068a9f891bc5ba5 + afabf8c3122d12d7ff3c41122d70d17d + 4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68 + daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9 + 9f5e2d1dd5454687873145ef6970fe06636195562fabbad9a3a76bf0dce03732a32ed87a326e3e8e9b1c5d0f41bcda54 + 802ccadfb7baaf0b6cf6579eca51f720; + aea3ccf860b00097 + 40763d96836c5f87b95460938de1288c + "" + 69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308b + fb81a3b2a097da78f981bbb53b2623f6271fd097fb6d126851ff942038904f0fb2cf4e265448c30df6a94559ae260d00a81af76545 + d9290c98d01f6032bf110b61657e165d; + a60076817523bd2a + bf1261b089d8f23a9c2835076a23faac + 2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa + 8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578 + cee153d3db504d8bb1d7050124952705e0eb9150cd5806e0b40f104eb15167512699f11b129604f7f36915159f592171dbb89b5604 + 5c96b8868aafbcb195e23f9335d73535; + c8ec4837898a92142b5b0677da1ac27311 + 7b45bcfff5d5f8b6fde2893232a9f81d + "" + "" + "" + b71d7a6b4f83e6276400173ddaeb0be8; + 14517ffae475f6b94a43a67b3d380d2f9a + aafe2dd721c0095c8808847689211450 + ba + "" + "" + 7c5df02df2e106fed4414626ae5b5315; + 8095ffab1eaadf66fd22ac1976063e113a + b61f813e28a1397a7974a1d7f4220c78 + "" + 5f + 86 + 6a7d0527c06c781aea0a6b0389048b08; + e426a5a0e80f678d404147842941feeffd + c2eb44dc8c0d5e8f444f7f4e0c893959 + "" + b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3 + b6c017318dda6d2389ab13ae89849c2944a151d982f0490074e38594c6f6a819c3ed133cca4493d84434228645dd47f7 + 6eebac1b2230b2fca6daefff666d4cd3; + ab6cf8556b7aa776945948d1b8834df219 + 6c92ec1718dcdeee0d52d9539726d281 + 0391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa + 4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0 + b1493269b6bc9b0c2a95e3b26c0df50fd48c5505c85d0f1cc545cb8ee4b9aa1917e71d2f8628a3b38d6282fa23d4021d + a6fe44618a21904fb885560b2dca9e2f; + a9aabb6c4e3c3554f8fb1ef61614c27029 + 5dfc0ca6551ca4bdb75359f91cb9d921 + "" + 056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3d + 5ad848d7910c43775ad95850550e36ed4f51a9180a1558752ef9043d53d15b7328f82cf31dd6e89fde07890019b7cba632600d6c87 + 58f508482940235912a6955d16d75ac4; + f6c2b3fac7cbcf96523d4723f91801325e + b8553236651c96788d73d192ee53b3f3 + ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f64b837 + bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b5 + 8450286f64f58e3f5cd1d62c28db59591ddf05384d3eaf824acdd8febc6f56595d91eb32d608beabe8f31117a5b42e8d38863be19d + cd0ddc15fdb0b43ab9c1da27dab961e9; +} + +serpent-pmac1 { + 60d7bcda163547d348b7551195 + "" + 86802543a1d8ca8f65b1bb3e0d31d221; + e77022907dd1dff7dac5c9941d + 26 + dbe75897dbb97ea7a0545fe684170ede; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1371206 + 13c3430e93df53d7da7833282eee3c25; + 34c9519848a877ff77bf79192a + 5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8 + 3af04cadceba44ec5a6897e499e82f51; + 8374d8cde8e160ad10997a21 + "" + 1d72b61bfec2412d29f3f0ecad5d04c8; + 635c6d62c9269029df3e6057 + ac + 3441e6813346f41a8f780f9921ccf0ea; + c87638f508046733d9ff61cd + bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 297ec48558af83ac8ebcb3e442fcfc8d; + 21b7f65b000961040ef2f9b2 + fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5 + 1c6db42246e98e9eaa43a287e5c7161c; + 4215abd6b3ad54ef + "" + e79dc50690f53356f567c3fe1845e31f; + c9a38378c5b93bf4 + f2 + 01c74df5d34de8442b6e0dea2f43cfcd; + aad2605faee2b03f + b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219 + e36a0ed637bc357b41d7ca57834fe1cd; + bfb474fd71d891f2 + 4bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9f + 1f2abc9e954b1e7d282ef8c3ee00fea4; + c2712a199e533fa9156308cdec3f768281 + "" + b498a64086f85b98d362950e079b3624; + e040a9b9a222bd689aef66f5306ceb0c6b + 08 + febb2df39da1126d67fa08e337c430d1; + ac8b0a22260c571b4a42bb8fdb233bfa6a + 5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65 + 7f8f5f88f99a29146523eec2910448f5; + b9aca338527ef19b09c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d + 0c21a0dd3a264c1ef7cfeebd6aa8c2c8; +} + +serpent-ocb3 { + 60d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9941d26 + "" + "" + "" + 4f7cf8f6ab514ac1f3727f957c772859; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9 + 06 + "" + "" + 49cd7a3bc7a32c2f5ef6c4097d9f3e48; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794846ecfa14a71 + "" + 30 + 22 + 1105ad05b7e04476b4c7a746a45538eb; + c9f137120634c9519848a877ff + 77bf79192a5b50ade5d9cd + "" + 739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + db5d464d5b9a3659805cb7a3e720721f7b6963be1c93ca3d5ad39b5bfb7d12aaedab640a6d098a0561198d05cd9fda2d + 25430830a120e8e713128afa579ce1cc; + 21635c6d62c9269029df3e6057 + acc87638f508046733d9ff61cd + bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 21b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a480 + 402dce04d49efb3aff4154a91ab4117d865b8c1e894e3e0170dbf421ca1a92addbe8599f92ffccaf4a96bf1ea5fe54ee + 00589c1be04b5aff3a9eba045c305801; + 30370c33d090c54215abd6b3ad + 54efc9a38378c5b93bf4f2aad260 + "" + 5faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219 + 48023bca0cfcdab03c28493ddbe3146a43b44d5037d87ca0c870c2c0fabb60896dfb1298de927f195884f29edd914e3e2097071103 + 6979cd907d468b65143ea75140e38ebd; + bfb474fd71d891f24bb65d1563 + 259f9eb53b571ea629c54d57dd2d + 42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040 + a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c + 559ea712ed9f509cf3ac9d44f1ac8cd0c6a11fd7e5250ce0de79f197f51f82903e8da278b4c5dbf8bcbebe7f52446cf523bee00462 + f15cb4b18193f4922298801f9323a3c7; + 037ba323fe1dc8151784873f + 0eb5b647da6794c18b5337685a96 + "" + "" + "" + b7dd404d4f1a01c8ef737b6c2525a3c1; + ed65b9aca338527ef19b09c0 + 63c46f88de9fd41e72d7b97e23e6 + ea + "" + "" + ab6815775c61984db8e9f4927af022a0; + bdff3bcd211499268878dbf3 + 0f1dad89d4b9b12012e4713df467 + "" + 95 + 7b + 70aa0ae770a0161e22bc0ae606c70527; + 630e7952d22bb02d7100b8b6 + 49377d20a8f083455b663e + "" + 4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f + 5ae21390a16833b1553ad00340cf88608eef0c77dec11bf992c8371c330f3c3b76484c95384949ec2cc42d1b943665f4 + e0bd36e53a42d1c06bc4ef6ac241d106; + 16e39815d4e9cfce3ed1ecdf + 3d264a7f16cb16c2e815f422cd + f0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4f + cb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb + a5b3449e8af9f06e72f5f618131e205714de08712af78c71173e347e29259efd49ef786eebfb7fe5592e2838ca92f9f9 + b6491d77b553f97cc3684ef4e7339515; + 1c8dd0b00951f284649016ed + 00456331854bc78bf43966eb0cfa + "" + 9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f + 0eb3df5285a44b93df6263d4a19c3468cc98d13cc57c92671fe450936feedb2d692d6e9b288ca7095ba3a16fc553d2b33f2e5e3285 + ed1441556cce090353a8e651db8b7765; + 30cbb7f0e4a973a8cd190107 + 314717a77456f3ff669c732b58db + 8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0c + ae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a4 + 72c70c50bfc9891abb5d0f389a48e4ba925f1a5de1b522dfec32d0de805500ef56a0e3b248e52d50461e8673b51591d76aa7aac188 + 22315e09ed36b5e886972e3d97bb191f; + 58cb948bdd409b68 + 7fa3a6827b480aa3a4c84cef64f6 + "" + "" + "" + 30c1077f4bdf19d1a75c2bdb0b791be0; + c9b53bf8f957f4b0 + 3cf43e89957f9a3e8128f8743d16 + 68 + "" + "" + 6f663abf27387105cc24b69ac2377f89; + 7b7bb8deb9bd205b + 70e04c091d205cdad9e9a79b1abf + "" + 91 + 74 + 81956eab259749fa15c9a0c287a3c797; + b0851e5ca605ac84 + 51399587011677508a15dd + "" + e524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0 + c229d22e2e97fdec03bf8725e466fe3130ef56c17c910ea6f6023fc4f389deb33eea058fd7878ee3f0947107da6ee92d + 5bea96a8d2416fbb9f616e27b8d67b62; + ef5746ea8fdcccd2 + 13e33f7e8a5718fd25014107c8 + e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70 + d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8 + 67125d08b30abdf348054dd642f18f0802d58b7ad3f49abd77ee6e68146696f42a4a73993f0d3fd2754033dfafcf0b49 + 51db397a26bccb5dfb66aa47d15dc1ed; + ad68daac90cfe22d + 2f1f2968cc42fa8b669ed3bb3542 + "" + a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69 + e20ad6334c2ecfaf8546c5917542e2b65b534724eefad63e1061805e673a6358d31753bdd4beb457112d41ccb39c306ae4aceb1fea + bb503bc1e42a7c837197827d4c4ba6ac; + d80ea12ff4bb5f06 + 9b8a2e86041c1b9fc214e9ca2186 + ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089 + d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4 + 13d0dff205001c5b6bf86c8810569bf634631c25dc146faf019d31b13437331abd317718f12e056d365c8d36520746656efd5fa8b1 + a281566357e03991bc302355006a4df0; + fa8fec816ac861a8b33779f09e7a10fc02 + a8f48afa3080ee119a52a9a817e4 + "" + "" + "" + 62e171992b3e9b84abd46d11865c70fd; + f2b94b0820cab383a8cffeea7c48631579 + 9dc875fba578c8ec4837898a9214 + 2b + "" + "" + c00cc0b5bacedb125f578b30d84d2198; + 5b0677da1ac273117b45bcfff5d5f8b6fd + e2893232a9f81d14517ffae475f6 + "" + b9 + 78 + 8a8a1da60db0bbd76cc5c4bcac79da2a; + 4a43a67b3d380d2f9aaafe2dd721c0095c + 8808847689211450ba8095 + "" + ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feef + 7a160e50b050bb3ca62c12501226cb0551b4dc3349721d71e08ccf2222dd831ac2a108691039f1ba41fc326d2a827bff + da9c04168e6dedb3579c2a9bd76f1692; + fdc2eb44dc8c0d5e8f444f7f4e0c893959 + b74dc23a7bb40e7e0013e51506 + 86d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf8556b7aa776945948d1b8 + 834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e73 + 7e0bd98a04cf07134ff5026bf10c6e2a4fcaead969223f4729ff57cc2d72f9c6976a03e4932fda63cacab98244f36385 + 34b97cb4b3ec851d86540afaefb7e6e5; + 7882cd09c2b9a80f34c0fde11c2481b11f + c76bfa4dbf710a9e544e0c536ca1 + "" + e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270 + 58c88119379227a3438f4be71c2b148eaae5dc87f047a10ac315de213b318eb0fd13be48c01b39654ec0521caa1da513b9fc1b9947 + 1176c87b5d31fb87b7454e7aff5104ba; + 295dfc0ca6551ca4bdb75359f91cb9d921 + 056b7de74fc9a9b37154ce6c0b39 + 6179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fa + c7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b5 + d5559d4ffc3be85cfdb261126b89cb7e7fae82a3f954bf79ffe6f7603ee58b5d2d37747ecfa24ad41bdaa0b1fd7c82e0e04e81c69f + 507ed27681b30a6cdaab64aba8bb3ac1; +} + +serpent-ocb3-mct { + 16 36d3bf694fedee5e20e35745d9f647e9; + 24 924c5b38d6df87dab11042e56bb0434e; + 32 5b8e3684bde5c8b28bb87796aaf95b17; + 16 506bd45f5b6eb67ceeb408b9; + 24 650f258975a5d1f6596ff2af; + 32 fd5488e927ecafd96722e92b; + 16 5294561007b55710; + 24 d3a5062ec84f5ac8; + 32 2b883de71615444d; +} + +serpent-ocb3-mct { + 32 5b8e3684bde5c8b28bb87796aaf95b17; + 28 1a93fd62a9e9a3cef4407833bcaba842; + 24 924c5b38d6df87dab11042e56bb0434e; + 20 626a7bdd05dfbed8287c7a7cec11b863; + 16 36d3bf694fedee5e20e35745d9f647e9; + 12 5a6486f6ba3b10d486c628147c71a85c; + 10 0664a0cdd817da522ce92837ec06ebc0; + 8 aa155e08b41857c4abe54180e6c50bbb; + 4 328cd59c0a989fb70c0339066da49aa7; + 32 fd5488e927ecafd96722e92b; + 28 f080658ee65dfd9d54e19ae5; + 24 650f258975a5d1f6596ff2af; + 20 d141c903a4d29332b36b2984; + 16 506bd45f5b6eb67ceeb408b9; + 12 3c53bf904f4edbb691e7af8e; + 10 849f7d73dd7e48655f062340; + 8 048b157a38f4281968f840e7; + 4 f52c2156342549de8bf99f08; + 32 2b883de71615444d; + 28 d9776aee81a378ea; + 24 d3a5062ec84f5ac8; + 20 e1e805b319485007; + 16 5294561007b55710; + 12 00edada26968f413; + 10 dff51ca249d51583; + 8 87ec3336240f6f98; + 4 305dce068342b3ca; +} diff --git a/symm/t/skipjack b/symm/t/skipjack index 63ac0cbc..2af56e9c 100644 --- a/symm/t/skipjack +++ b/symm/t/skipjack @@ -99,3 +99,246 @@ skipjack { 06e3c0e541f4aae6fe93 40009f8a465a9feb 0e7aace421bc79d8; 2ea09f1cc89e064f09bc 543208b05bfa3858 a95d87fad12c3593; } + +skipjack-cmac { + e4bef260d7bcda163547 + "" + 5a0fba9745b5a83e; + d348b7551195e7702290 + 7d + 8610508eeee08d29; + d1dff7dac5c9941d26d0 + c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689d + 46b1504483d84dff; + aaa9060d2d4b60030623 + 65b0a54364c76c160f11896c4794846ecfa14a + cffcc55881902725; +} + +skipjack-ccm { + e4bef260d7bcda163547 + d348b7 + "" + "" + "" + a8e3e588; + 551195e77022907dd1df + f7dac5 + c9 + "" + "" + 3b47dc26; + 941d26d0c6eb14ad568f + 86edd1 + "" + dc + fe + 61bfe011; + 9268eeee533285a6ed81 + 0c9b689daa + a9060d2d4b6003062365b0a54364c76c160f11896c479484 + 6ecfa14a7130c9f137120634c9519848a877ff77bf79192a + 3599e35441a20dab5e973151a0f3d8dbde983d9a896d3463 + dee97ef167dde431; + 5b50ade5d9cd739a3d1f + 337f29549e + 6b0d27a4ba234085406a6136512061f7080cc0 + 7df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029 + a72ba97fe436bdad5e7416aa41b733be94324faf2d70cc67a31559f7d7 + d14f0eba040f800d; +} + +skipjack-eax { + e4bef260d7bcda163547 + "" + "" + "" + "" + b15f1791e4065ebd; + d348b7551195e7702290 + 7d + "" + "" + "" + 58aed98d9796d86e; + d1dff7dac5c9941d26d0 + "" + c6 + "" + "" + ed16d102bdd549c9; + eb14ad568f86edd1dc92 + "" + "" + 68 + 1c + c1a5644ab08ad1dc; + eeee533285a6ed810c9b + 689daaa9060d2d4b + 6003062365b0a54364c76c160f11896c4794846ecfa14a71 + 30c9f137120634c9519848a877ff77bf79192a5b50ade5d9 + b4bb56af916bc1a14e6a106346b9fbc1989b20d12275469f + 06a4958aa50a4260; + cd739a3d1f337f29549e + 6b0d27a4ba2340 + 85406a6136512061f7080cc07df0591d8fa21f + 2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc876 + 1e9afd31797d761c4f9ffbf0031a227872fa8b21de658b8fdb22514c48 + 44adbb6a2eae0a93; +} + +skipjack-gcm { + e4bef260d7bcda163547 + "" + "" + "" + "" + 6fa498e64c57905e; + d348b7551195e7702290 + 7d + "" + "" + "" + cc2fd0c06756c545; + d1dff7dac5c9941d26d0 + "" + c6 + "" + "" + d6c1997db60c0a1c; + eb14ad568f86edd1dc92 + "" + "" + 68 + 98 + 08825f061a3ea120; + eeee533285a6ed810c9b + 689daaa9060d2d4b + 6003062365b0a54364c76c160f11896c4794846ecfa14a71 + 30c9f137120634c9519848a877ff77bf79192a5b50ade5d9 + 0a048d8b451ed2cd53dc70a177834525881e84046c4dd904 + 222801fac5bfd46c; + cd739a3d1f337f29549e + 6b0d27a4 + ba234085406a6136512061 + f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029 + f3bf97b9c9c15761437a42c826abadf01e9207fd4b172e200a6d7aea3a77c85c3a + fff6db552209b7b8; + df3e6057acc87638f508 + 046733d9ff61cd + bda3b3e9878731ebfedd4705e505da1435dcea + a7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + b96e1e6d2db5000c5bbbd06e86ab26c3a2a060b3eeeb1899793a743bc9 + 74694b07f5866d80; +} + +skipjack-ocb1 { + e4bef260d7bcda163547 + d348b7551195e770 + "" + "" + "" + 28afba7b57208bb2; + 22907dd1dff7dac5c994 + 1d26d0c6eb14ad56 + 8f + "" + "" + 62f000b7bdb0d1dc; + 86edd1dc9268eeee5332 + 85a6ed810c9b689d + "" + aa + 84 + c92bec4a841eab50; + a9060d2d4b6003062365 + b0a54364c76c160f + "" + 11896c4794846ecfa14a7130c9f137120634c9519848a877 + 50d328a84a166d75e1574aafc3a6847451f766a4e5b1d506 + c155363b2c86bd70; + ff77bf79192a5b50ade5 + d9cd739a3d1f337f + 29549e6b0d27a4ba234085406a6136512061f7080cc07df0 + 591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9 + b9f8bca7a0f1024a232217f4d9acd0187997bdb2348287f9 + d8d3f45231b59769; + 269029df3e6057acc876 + 38f508046733d9ff + "" + 61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c3 + 3b5a6606907f297d26827ab95798171debff551df36e0ae8f6f29026f8 + 24734c1d6c3da996; + 8201a894476b3f102b75 + 2eb9529533966f27 + 043eb621b7f65b000961040ef2f9b2fc5fa450 + 727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a + 694a1412b0ab1b6fb698a9eb920fd2910c7625b68558fbe9ffda426f55 + 19c658ead145b558; +} + +skipjack-pmac1 { + e4bef260d7bcda163547 + "" + b663da5674ffc5d1; + d348b7551195e7702290 + 7d + 554a2fb9de2d30ae; + d1dff7dac5c9941d26d0 + c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689d + 0318df96a103a2f1; + aaa9060d2d4b60030623 + 65b0a54364c76c160f11896c4794846ecfa14a + b3a737b39bf1c95d; +} + +skipjack-ocb3 { + e4bef260d7bcda163547 + d348b7551195 + "" + "" + "" + 306c2123c229d86a; + e77022907dd1dff7dac5 + c9941d26d0c6 + eb + "" + "" + a0f5e0a9d6193d8e; + 14ad568f86edd1dc9268 + eeee533285a6 + "" + ed + 76 + b1f29902bbde9441; + 810c9b689daaa9060d2d + 4b6003 + "" + 062365b0a54364c76c160f11896c4794846ecfa14a7130c9 + 62299168f2ce7ea1488f71fbde61613002efcc4815d4674b + f9d14a84093df62a; + f137120634c9519848a8 + 77ff77bf79 + 192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba2340 + 85406a6136512061f7080cc07df0591d8fa21f2dd88374d8 + 7ee7aa9e2d4e7e5f4b9c9e254ffd3868f8ce577bc82b0239 + 0560b1fcaba5682f; + cde8e160ad10997a2163 + 5c6d62c92690 + "" + 29df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + 914f81636ba12b551c60b41dcf566e447d02d15d2113c09678b1fca4ae + b7161acf1efb88ec; + 05e505da1435dceaa7b1 + cc49ae1d50c3 + 8201a894476b3f102b752eb9529533966f2704 + 3eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d + 78498440ea075861116531b9ad62fa7d399948260edc0bdd04e04a4327 + 39de18c8572cfd02; +} + +skipjack-ocb3-mct { + 10 63be3f7aef5a5f98; + 10 dbe0b1ff8673; + 10 b26e14c0; +} diff --git a/symm/t/square b/symm/t/square index 7b348e2d..9d0cbf9a 100644 --- a/symm/t/square +++ b/symm/t/square @@ -521,3 +521,687 @@ square { 00000000000000000000000000000001 0f1e2d3c4b5a69788796a5b4c3d2e1f0 69bd984641e0aa887bc23738f60070db; } + +square-cmac { + f260d7bc + "" + 29984a33657f622352c1ee581eab804e; + da163547 + d3 + cdc5e3485007695cdeb53ce1e8cec39e; + 48b75511 + 95e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003 + 7fdd1689e5a004d05b0bc92e3ecc8f16; + 062365b0 + a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd + 95f37b226b5f157fb68c9b235085799a; + 739a3d1f337f29549e6b0d27 + "" + c48de9e2768ea55c731b65c22052aebd; + a4ba234085406a6136512061 + f7 + 4710b0fec299631f0d53e9ce3b0a172b; + 080cc07df0591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + 88eeeecc2b156790ac07c7c4c7b6c431; + 05e505da1435dceaa7b1cc49 + ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a + ac18ee08b5e9a21581b33f73b63e9a41; + 9b542cde52ebfda1 + "" + d45f57812f3249ba56239bf41459682c; + 9d0ccc520f215eb5 + 7b + 12f4a147fd87d19814850cea849fab85; + b3a4f3ebbbb18ac6 + c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b + 950e0997bc4188db73c08df2e1e880a6; + 69ac26afa3349829 + b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d156325 + a1fa99cf13347b5b803ccc6c2e183381; +} + +square-ccm { + f260d7bc + da163547d348b7551195e7 + "" + "" + "" + 6f6ddeb0; + 7022907d + d1dff7dac5c9941d26d0c6 + eb + "" + "" + bba9ea11; + 14ad568f + 86edd1dc9268eeee533285 + "" + a6 + 0a + 507bd8ea; + ed810c9b + 689daaa9060d2d4b60 + 03062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd + 739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + 2de5299d997f5a95d32115f84b8cbc072043580e27bb6ace6654173512e0d464ce4358899c43ac2befe5cbe68155797b + 217a8c66edf6aad2f17f555c8936028b; + 21635c6d + 62c9269029df3e6057 + acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a8 + 94476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57b + f88c7d34053cc7278c3e3b09715ab3dec3aa050aa70aa6dcd560a9ea58ddd10857b9bcffb98e2af8a3c851f60f540ab8872af0df1d + a65b843ead57238ecd6bf0eea46d6fbe; + b3a4f3ebbbb18ac6c95a97a4 + 8030370c33d090c54215ab + "" + "" + "" + 345fc32c; + d6b3ad54efc9a38378c5b93b + f4f2aad2605faee2b03fb6 + 48 + "" + "" + 89dc30e5; + e27fff63102758fe2b69ac26 + afa3349829b94586306fed + "" + 54 + ba + 595a1d50; + 154f8f28523c03d4de160015 + 7846b710ee72807a22 + 19bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b + 0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a + 562758f6a2b849784695d8f36b992eb75a439f9e4daaffff462c1c0e2ed738ae81857040c7bc33093d5d962635b162b3 + de5af35682b227c7c585fd7ac841b903; + 42bb8fdb233bfa6a5cfb0bad + 7d95214ade49cb3b6f + 5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b + 09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d71 + ef06fd51aee9d8dc17ae50cb1aede6b88f5a5f0e2bfa12f825ef09a757e06a1fd2571bc34e3d6796ea05613d6323cf0ea90dfe15c8 + efd15ead8ef69008007fb696c5e0de7b; + 00b8b649377d20a8 + f083455b663e4ee1315f3c + "" + "" + "" + 6f0d9e5d; + 8f2aebfa921451dc + d1af5813b70d30ce2f1fef + 6e + "" + "" + 76d11bad; + f315d0798391805d + a08da3aefc5f8584b7c5e6 + "" + 17 + 0f + 8aa0fb43; + 669c0f16e39815d4 + e9cfce3ed1ecdf3d26 + 4a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986 + 981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511 + b98ec80c9bfcbbf817b03abb770cb6121b7dbf4b497b1af44e9c910bfa324279416423f51b97738f01f27c70436330ef + 4d5d0ebb6586b5e8405e66fed4c0361e; + 265febd11c164720 + eef9eb1c8dd0b00951 + f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc28 + 10d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c73 + e948dd0b7f57ae2f94ed538207db42a1f4e3e743aa1105e600284b3b92ce82b4c99ee0a2db8f7f51d17a7084aa068eba1a1f0cd0a7 + 401f2e64af6c6d18382d1546abe984e4; +} + +square-eax { + f260d7bc + "" + "" + "" + "" + 66848361a1d85500e3efc4889f3c2bd1; + da163547 + d3 + "" + "" + "" + 3e14f9c0f9b208db9a52730d00525dc6; + 48b75511 + "" + 95 + "" + "" + 1b81e7698ff5e258ea2e8f75b7bcfd88; + e7702290 + "" + "" + 7d + d5 + c256dd01d1ee4db1387ef0f0b3d43b57; + d1dff7da + c5c9941d26d0c6eb14ad568f86edd1dc + 9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137 + 120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080c + cd9fbedf0befc513ec208493902b99f4e304654e0460d29920804d69dc150fa3e31d86a755ba930d0211fee9b7ca5f9f + f01b0b0089bf48fedc2c21556a1b644a; + c07df059 + 1d8fa21f2dd88374d8cde8e160ad10 + 997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da + 1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b54 + b88f48021b69e18d9457120fc11ebdd467c0b1119b5ab0bd16a5c3aa70e263d3ab841cbe6bba4fd02c94690dd143746294f825c26f + e0efd3bd220277de49de30272939c21c; + 2cde52ebfda19d0ccc520f21 + "" + "" + "" + "" + 8eac437bb3e523a1588a11e05db64b05; + 5eb57bb3a4f3ebbbb18ac6c9 + 5a + "" + "" + "" + 8950206e80699724eecfcaa54766d533; + 97a48030370c33d090c54215 + "" + ab + "" + "" + ddde409a326fe6d98ce631e1da7f54eb; + d6b3ad54efc9a38378c5b93b + "" + "" + f4 + d8 + 8288b113a8d26d40aba09cb3f2195dd8; + f2aad2605faee2b03fb648e2 + 7fff63102758fe2b69ac26afa3349829 + b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b57 + 1ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f7682 + 4d1e0a695a91107ecb1d5247d28cfbf19237fc3f63e45f068d11dcbda21d83edcba5bdf9d3f06c2c8cab82fc41bf95dc + 530d31b751cdf63e4d3f69dbd3623c8a; + 81e040a9b9a222bd689aef66 + f5306ceb0c6b08ac8b0a22260c571b + 4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5 + b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1d + d547e342eb52d40545b00733505c306065b84193dc67ad9436f2acff5224cfe199885811c635803ec7d36a4756a55f97a7d79de113 + bed4ee2118bb4c7b7a12e34c60b7db7a; + ad89d4b9b12012e4 + "" + "" + "" + "" + c2044f9358ab48997b37cd48c3d71ff0; + 713df46795630e79 + 52 + "" + "" + "" + 7170fe71433b54c9891444470353f8ee; + d22bb02d7100b8b6 + "" + 49 + "" + "" + 070caac7af2fafb9acbc0dc299952b52; + 377d20a8f083455b + "" + "" + 66 + 91 + 1871fba93a1bd987dd232ffd84222d45; + 3e4ee1315f3c8f2a + ebfa921451dcd1af5813b70d30ce2f1f + ef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f4 + 22cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8 + 34bea45625f646aa4fea5c08966df347998c5e91c3e243ddbae6ec95cbd9aef41e52e5bb71cc8d38470075e5f342d0a5 + b7d0633c6ed773da8c265c633cf8ebcb; + bc4fcb70e27e98ef + 1f0446b42fb144d44b6d00f06dc188 + d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331 + 854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5f + b11e564fe1caa81babd189007d9fdf983b4a086302d1eb98daec4f6c91849f873b84982b0a5c037b952355e0a0c916a3967e7ddb69 + b87b90233e12e003b8ffc0fa198d2269; +} + +square-gcm { + f260d7bc + "" + "" + "" + "" + 66ac17c939ebd05ca617e77ba83201e9; + da163547 + d3 + "" + "" + "" + 8361e8e723233ce477ef9132624bfb9e; + 48b75511 + "" + 95 + "" + "" + 29a7e874d6054c42dcc1ada2e6f38cf8; + e7702290 + "" + "" + 7d + 7d + d439d2be5e01a0d767739abd80dbc293; + d1dff7da + c5c9941d26d0c6eb14ad568f86edd1dc + 9268eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f137 + 120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080c + f36d7d44b8637a2a560a8e89a7a5a5c754de68194a47bb2befdf2384e91eb38cc70807a42a687eb3113c9c223e1c8763 + e13b8f67d62247d887180b4cfb90eb6b; + c07df059 + 1d8fa21f2dd88374d8cde8e1 + 60ad10997a21635c6d62c9269029df3e6057ac + c87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27 + 863f1602c0fb45b1a3264e8140b5addd0a82feb9b5e632fc539b3ed83667eecbf32c65dcacec865ea475c3506d61d00db1ba24288ba1a13ef1 + 58de876618ed18d0aab09ef9acd06bae; + 043eb621 + b7f65b000961040ef2f9b2fc5fa450 + 727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6 + b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c + 1e559d1bc26402ae885ebcb0946a573d44df5d59476510247197bc816467f5386887c5543f3a2256e26f44a91b31afcb7bcc85b2dc + 83783d53918eff6b310540ac8c1c5d85; + 03d4de1600157846b710ee72 + "" + "" + "" + "" + ddd01942ddf92df99dcada451c651de0; + 807a2219bfb474fd71d891f2 + 4b + "" + "" + "" + 85e41566cb1b62bbe5c3e3a2a5f35779; + b65d1563259f9eb53b571ea6 + "" + 29 + "" + "" + 212a5e2129cd24e177c03718181637d0; + c54d57dd2d42f70800df9fcb + "" + "" + ac + 28 + 1b1cb85207cef5e0fe224f9b1d77f836; + a48b77dba189196d1ebba10b + 0467cb9fc2712a199e533fa9156308cd + ec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214a + de49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b + 2e5f808b009e36fb4f2cf59ec0cdd6f7aac023b9e6037528879a3389aca459a56a337073116aadb30f44453a3bd540df + 637a59d017456d0fffea63306283df28; + 09c063c46f88de9fd41e72d7 + b97e23e6eabdff3bcd211499 + 268878dbf30f1dad89d4b9b12012e4713df467 + 95630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805d + f37ebcd6beca3d239c15bc8e98b774a0c527c87c6fa04ebed3098db72f36ddccba0ee84417d99156b229b6a9b3d6b0d4139233e7d6793618a7 + a21999c562eaf6d513e48d6a0e12d77c; + a08da3aefc5f8584b7c5e617 + 669c0f16e39815d4e9cfce3ed1ecdf + 3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd + 52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae98 + 5e606cf43bfe84c8a64a2ab5d04d377da99053d2dd80b4b9e3b161a04b58b96bc7b750b95fdb479d36cebaebb300526d6d3c8a97e1 + 7d73467c21c6b79fd07b6670875687f9; + 5511265febd11c16 + "" + "" + "" + "" + d06bc05e975b21905cefbf33aed2558b; + 4720eef9eb1c8dd0 + b0 + "" + "" + "" + 6088d2aa7493efa2bb71465f9b4a4a7f; + 0951f284649016ed + "" + 00 + "" + "" + bfc486eed4840dddb9b8eb5cdc0895bb; + 456331854bc78bf4 + "" + "" + 39 + 22 + a44fd42c2bed09a530a167ff512d53c0; + 66eb0cfa9138ddc3 + 9908445608fe95e81c2533e31c9c1a98 + 51bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717 + a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945f + e7ef1f4b63cb4ab8b7ee9c733450f6bf4f921ca5fef77eaebb8cf2fd614e0de3f87e22a59b20f4f7af7af8f9c2175924 + 1b90917328ea382e254f6d0aa8d8fb50; + fd505003cc0cae9c + e021a5f1fa4ffa91544485f1 + a1258b2b9b8f0911e32d65cc1770a18cbfe6ef + fd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a + 90f4bb5b8e60ae32eb97f506c90a0e71156ec2e4a39c1ae669502bbbd6724a3f5713dcdcdacb374f31723a9003a8402dda6b0260362527a72f + 2256d08180ac3ed3ab48daa0b86d4cc0; + 3e8128f8743d1668 + 7b7bb8deb9bd205b70e04c091d205c + dad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d + 65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8 + 58a997404e629f9e9d5652bd076188c9bd4a631d3e2486a944151f3cf29edbfc62e3910c0b341052b475d623f2339488c9983e0990 + 1762e398f8582d72954ed718af4f677a; +} + +square-ocb1 { + f260d7bc + da163547d348b7551195e77022907dd1 + "" + "" + "" + 4ec5c312526c730e41458aca324ae0a0; + dff7dac5 + c9941d26d0c6eb14ad568f86edd1dc92 + 68 + "" + "" + d0cc24f9084261cdaf4393e7b250701b; + eeee5332 + 85a6ed810c9b689daaa9060d2d4b6003 + "" + 06 + 72 + 1e1671f47f5bd8b32ebb09c019105281; + 2365b0a5 + 4364c76c160f11896c4794846ecfa14a + "" + 7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a613651 + 11e134a63441fc0951b37098764822d6eaa47187fe96a2f3658563cc612c857f0dd5d4e056c820a3670828dd7f5a9d1c + 86893621402b0a64fded1b34d47504fb; + 2061f708 + 0cc07df0591d8fa21f2dd88374d8cde8 + e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd4705e505da14 + 35dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450 + 1599b31480519c999bbc9fd4fb1a24676071040c16ff4a6834cdaf46c51ccbb9522cfde0e2df2867871cabd4aa73c33a + e8e411a4ac803610a4f2a8e1b6aabba9; + 727a9b54 + 2cde52ebfda19d0ccc520f215eb57bb3 + "" + a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758 + 384781d5a43f9e0d692787efd9cbbff3f8cc6e154544695653e495e63b3da9730b781b214f5c8f6d940542c76c24f0acacfcf099c0 + 5fa2cade7fa22e8df91b9f91593f9d3a; + fe2b69ac + 26afa3349829b94586306fed54154f8f + 28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d + 57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689a + 4c8c3874f73c8504b64bbe612589c103a462720d244c3092221b6c7b31a162aebefaea934d2ac8eb9e03f8f480aa1407d58a8a8e0f + 03fa1ede942984e0ae4f30946f7e0201; + ef66f5306ceb0c6b08ac8b0a + 22260c571b4a42bb8fdb233bfa6a5cfb + "" + "" + "" + ae26bcd1fc7065f659ec2e37cdbb4d06; + 0bad7d95214ade49cb3b6f5f + e8368131115c037ba323fe1dc8151784 + 87 + "" + "" + 9f5a8cdf70fc430a52be4efbe40903b5; + 3f0eb5b647da6794c18b5337 + 685a96ed65b9aca338527ef19b09c063 + "" + c4 + b1 + 5358be539c81b8af364ee06a6d510baf; + 6f88de9fd41e72d7b97e23e6 + eabdff3bcd211499268878dbf30f1dad + "" + 89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dc + 6a33c5e3320001aceef2ddb9eb101bc7a44cbbbe05a3a4fffe25cc658d1a5834701a2fd135d964d2aafa112d45c44727 + a1b70c95ccff432cd7ffac9fcfc36d4b; + d1af5813b70d30ce2f1fef6e + f315d0798391805da08da3aefc5f8584 + b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb6 + 58b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d + 92a2d4564bf2ce07ddfc07a4c61b642f82e07603156c3e67a21fc29958ae1ab0f11689b5361185a5e36e11f8764939c2 + f4f96b643edc928c53440ca84037253d; + 00f06dc188d472a784e0c6f2 + 1195a3b9f4ae985511265febd11c1647 + "" + 20eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc28 + 6850774629192af796f0a661a429cfd5a235499b4f839206ab9a23dbeed0566217317c51538556edf394c8d83dffedfa381222d7f6 + bf6ea195e668f32372ecce468c963344; + 10d858cbbc8424d126b807e6 + daa089c3f9099c5ffb824173d7634c04 + 226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b73037 + 4ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65 + 5016f4b0746fe26e4c8ff63a0fb3a3af5070ba789900e4b69b90c42331d2bef65a6d520ed660c6b8b21180a3e0706e57b6f8e99680 + 5336c139328f5e30663524991bca106e; + cc1770a18cbfe6ef + fd1ff6778554acf1270485b203a3c1c4 + "" + "" + "" + 68289e95ba9adc986ec25334e9821681; + c967c0a458cb948b + dd409b687fa3a6827b480aa3a4c84cef + 64 + "" + "" + c3fd1e84842901c9030c844f1cf2a037; + f6c9b53bf8f957f4 + b03cf43e89957f9a3e8128f8743d1668 + "" + 7b + 4d + 65211e0de7d279e5ecde8793097d5217; + 7bb8deb9bd205b70 + e04c091d205cdad9e9a79b1abf91b085 + "" + 1e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7ef + 8cdbd696f4e8b357c8077fd749e4bb0a0f24c8b95deebd0174708f13d6656315c47a9fe9cf561d4afb4e48ab68249248 + ba46b27e9799540b1f2fed90f8404169; + edef3401539c51d2 + a90bbf7f1bfc338ab0ef5746ea8fdccc + d213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5 + afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2da + f227e7487fe14220150b10fa5456bf655b53c2b3cd2200ee882b912d9ad71146f8a937eae0ac4fbdcc99602783caf769 + 0d78408bce85318de6bcfd8cdc7579ff; + c07ecde95759ac46 + fee6dda7abc8ad68daac90cfe22d2f1f + "" + 2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d9683 + 88e08b26d8c6c245d09dedb7a2b2482f0a5816940b89e87ed5c3a0ca573d2b8be39e18d252d84b4d9aad35fc54dbc57306c45676c9 + 2d9921c55910b5fd930615d61dde717a; + 6c5f87b95460938d + e1288c69d80ea12ff4bb5f069b8a2e86 + 041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076 + 817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e + a450198ec39d53163f8db0c90b59a3b5d02dd4ae0c5c800e9b30bb747082e383ffaf85cae517a18ce337b064f74286cf8d843e0696 + 5a40990ae1dfae2c5cd30d9b32c794c5; +} + +square-pmac1 { + f260d7bc + "" + aec43cacfa9e76ed9f6c0176974d1111; + da163547 + d3 + 38e2ce3d69f8fb21ed28599d77607fe8; + 48b75511 + 95e77022907dd1dff7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee533285a6ed810c9b689daaa9060d2d4b6003 + 7c8785ab3dcb7d71ba3d6fcf7ba32376; + 062365b0 + a54364c76c160f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd + b21eb39143554c29a104eb7ca8d10ca8; + 739a3d1f337f29549e6b0d27 + "" + 8a5016e4834fa9fe8ef64746a89189ce; + a4ba234085406a6136512061 + f7 + 21e70bad22188fa3845c86a33d466528; + 080cc07df0591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + fdb16c9e5914268aa7dca6ee20efb72e; + 05e505da1435dceaa7b1cc49 + ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a + c69607969a66a1f0e09c40a8b8e7b303; + 9b542cde52ebfda1 + "" + 718839aeaf776c252d578376fe739e46; + 9d0ccc520f215eb5 + 7b + 4830cb31ec114ff8704f183f95d06200; + b3a4f3ebbbb18ac6 + c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb648e27fff63102758fe2b + c5aa56a0bf29d192de4e3db9174b1b9a; + 69ac26afa3349829 + b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d156325 + e6d24bd14f25e2fe8909354cdac337f5; +} + +square-ocb3 { + f260d7bc + da163547d348b7551195e7702290 + "" + "" + "" + b1669cbf9b59f73b4288eb0761332190; + 7dd1dff7 + dac5c9941d26d0c6eb14ad568f86 + ed + "" + "" + 780716f09513ecb8dd6f322f3901fd27; + d1dc9268 + eeee533285a6ed810c9b689daaa9 + "" + 06 + b8 + 1fcf843450fa4d3da50d8de6525119eb; + 0d2d4b60 + 03062365b0a54364c76c16 + "" + 0f11896c4794846ecfa14a7130c9f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d + 33f91dd536f3667b220ac4fa9ef6bec830fc052968f5c3c78141ad56254dbe7fff02e85ea5a278bce0c9a5037caa31f0 + 11621f557ad6c52a82e8d9495bb284e2; + 27a4ba23 + 4085406a6136512061f7080cc0 + 7df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3 + b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7 + 1859d78e9ad0fbc8bf76a97f08e6de088994238974dce458f7dc145948b8ba9f8b8f52c82a1ff60046350eeec8936379 + 350f84d218392b1282daa7db5ebc4e5e; + f65b0009 + 61040ef2f9b2fc5fa450727a9b54 + "" + 2cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aa + 664cabfb69a25342a0bcc17049c316c78c412df3efbf75cc192b936dccf87b3c094d51468c20911a477cd6a214c403ff99abec313a + 09b989eae5e6973b675f06ab4b9ad1e7; + d2605fae + e2b03fb648e27fff63102758fe2b + 69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d8 + 91f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9 + 9f53984003391daa1fe81c1e9385d1d902f330b930b225a8164f06adeaff820d08dfceeba9ae1a9639d556bba8ad6563186d022240 + 64d960c38db07c9ede67bd56b122544e; + 156308cdec3f768281e040a9 + b9a222bd689aef66f5306ceb0c6b + "" + "" + "" + c09ceb18e7c3a8ac514ff85bca3ff3c5; + 08ac8b0a22260c571b4a42bb + 8fdb233bfa6a5cfb0bad7d95214a + de + "" + "" + 80ad7d8b14ff64d06b79cd39c7440775; + 49cb3b6f5fe8368131115c03 + 7ba323fe1dc8151784873f0eb5b6 + "" + 47 + 74 + 6e58478155a6c0007a0323c4235d8e70; + da6794c18b5337685a96ed65 + b9aca338527ef19b09c063 + "" + c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb0 + 867bb322577ed2e766f857c22e0114e95c6ffa900fb90bc3937effe8dfa93140d9a58ba0827e5b06c1304ef17fae2c33 + 0e880f9fe586b0761eb98b29b1636b65; + 2d7100b8b649377d20a8f083 + 455b663e4ee1315f3c8f2aebfa + 921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3e + d1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd5214 + 738258f0995345cfb20acfae2607aeb91871d5a7b704a82e866350f8e3a28dadef97edc6b7618a12967000642abd3cbe + 6a41eed95fa7c3c529eee84ea0a4770a; + 7ed12ca986981a874498ad0a + bef8bc4fcb70e27e98ef1f0446b4 + "" + 2fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed004563 + fe2c297cdc8e4761c2d70f8ac5c8431bbdc7560712b651f182aa471c5fa6d9569d0f890c8ab2a5dc6e6e61a130a20d533dc013b6e7 + 1722ffbd31d1def40cc073828ccc4cfb; + 31854bc78bf43966eb0cfa91 + 38ddc39908445608fe95e81c2533 + e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4 + a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6 + e55a772b18315f4096513d5bf39f4c42665be5375ccee48d7f7c9bb8ad05644e2a2d92b485a2c42514e2abb4940045ed05b2d15bfa + 01a830efc22048f44dc01e1db446b5bb; + a9f2c0945ffd5050 + 03cc0cae9ce021a5f1fa4ffa9154 + "" + "" + "" + 75029ca958d142837b6cd9138b81c0cf; + 4485f1a1258b2b9b + 8f0911e32d65cc1770a18cbfe6ef + fd + "" + "" + 8568e94583082cdd23e3f72b9f28d106; + 1ff6778554acf127 + 0485b203a3c1c4c967c0a458cb94 + "" + 8b + 4e + 10be6791bce4cff5866df5348e7e9ef3; + dd409b687fa3a682 + 7b480aa3a4c84cef64f6c9 + "" + b53bf8f957f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e + 4511dc2330fa5033e1ac63dd1901ed10c5c919a6eed4e953cef5b7847f86f6db03d68301a6dea2c4f8ff6173da5800a7 + 8bd0072dd3ca8de80eddb1cfca3680fd; + 5ca605ac84513995 + 87011677508a15dde524af3e2b + ee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8f + dcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc + 2212a8678c5de88205f0fea2785f6dbe17d974ff4d64a533c573ca6d9a8079a55bd3241f6783705d81498a2426d522d3 + 0e895642d052f0695d3ade0d052738cd; + 5ba5afabf8c3122d + 12d7ff3c41122d70d17d4569eaff + "" + 59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f29 + b5e9c68bbf184cfaece73aa7d566a115709a25c94217851433e62f2a28aa9d45a084f521fc5514af2f66c573ce79d817d74a6480b9 + 613c417ce774d4a717ea6a5fd0ee5b06; + 68cc42fa8b669ed3 + bb3542a9cf44bbc8c6254d980398 + bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69d8 + 0ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba600 + 08a8bccee9fb6b7449fdbd1dfcb6836385770d4f6592e27c563250f869ad4262a87159fc9a0d42b61e1f59acfa244c7bdee8cd03ef + f5cf62fa77aba0b2285dc3d231ae2cd5; +} + +square-ocb3-mct { + 16 47b0a29f45c1b000f1a0c27eee7f42e7; + 12 7a80e7d6e556778f77a327928ff4dc35; + 8 886bfcb71cd24995911ed011b231d99e; + 4 d0b2597b73f284932af5a5db0fd1fb3d; + 16 5c3d0dfbee0d8977a7cee660; + 12 6057212ee2684bb36520d44b; + 8 5f0f721b8171461d242bb883; + 4 127b569653ace9af8aac7f47; + 16 4184125b37fbd3fc; + 12 258e75d36b5359b3; + 8 bd8c4a18f64be7cf; + 4 55a5c5e40c4de0e9; +} diff --git a/symm/t/tea b/symm/t/tea index 9eec55d0..e76f9eff 100644 --- a/symm/t/tea +++ b/symm/t/tea @@ -72,3 +72,912 @@ tea { c86c21d8c26dc291f662c8f2fe79b74b 0993d3b68c1d4a5d d33c2e41dd5da131; af4f4615c7c298639b9728251991419f 1e268f9e710313b5 a9478f8cf88b7e10; } + +tea-cmac { + 60d7bcda163547d348b7551195 + "" + c9d9c939fb01921a; + e77022907dd1dff7dac5c9941d + 26 + 71bafd3a810cb7fe; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0 + fa579abf1f086cd6; + a54364c76c160f11896c479484 + 6ecfa14a7130c9f137120634c9519848a877ff + de36e64b775dcb5c; + 77bf79192a5b50 + "" + 7d4dff89fcd86251; + ade5d9cd739a3d + 1f + 8ebb09e514e0fff8; + 337f29549e6b0d + 27a4ba234085406a6136512061f7080cc07df0591d8fa21f + c079db9ba9f93c6d; + 2dd88374d8cde8 + e160ad10997a21635c6d62c9269029df3e6057 + c57695c67af0e83c; + acc87638f508046733d9 + "" + 26c7bc682ced6dd4; + ff61cdbda3b3e9878731 + eb + d26aadbc23507937; + fedd4705e505da1435dc + eaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533 + 2b121397d4ba05e3; + 966f27043eb621b7f65b + 000961040ef2f9b2fc5fa450727a9b542cde52 + 06d48234005d0d34; + ebfda19d0ccc520f21 + "" + ddc6b8ce28333159; + 5eb57bb3a4f3ebbbb1 + 8a + e5a427c9e3c9b30d; + c6c95a97a48030370c + 33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260 + 3994c72240c20e84; + 5faee2b03fb648e27f + ff63102758fe2b69ac26afa3349829b9458630 + ac308d1e150a1c6e; +} + +tea-ccm { + 60d7bcda163547d348b7551195 + e77022 + "" + "" + "" + 530b9b73; + 907dd1dff7dac5c9941d26d0c6 + eb14ad + 56 + "" + "" + 0b824023; + 8f86edd1dc9268eeee533285a6 + ed810c + "" + 9b + 61 + 1cfad40f; + 689daaa9060d2d4b6003062365 + b0a54364c7 + 6c160f11896c4794846ecfa14a7130c9f137120634c95198 + 48a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e + 9e8ba32c68560a3f15c30cf5a03a842fd9b0fa0efe2cab90 + 1380f2213a0ab1b6; + 6b0d27a4ba234085406a613651 + 2061f7080c + c07df0591d8fa21f2dd88374d8cde8e160ad10 + 997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbd + eb7a05983eb9b9015770af0d2c48f693102f1b74249ce318fb8cc63b25 + 5624c3dd7fbb9480; + a3b3e9878731eb + fedd47 + "" + "" + "" + 4567c460; + 05e505da1435dc + eaa7b1 + cc + "" + "" + f8bc87fa; + 49ae1d50c38201 + a89447 + "" + 6b + 50 + e52efea4; + 3f102b752eb952 + 9533966f27 + 043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542c + de52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a + 66f563e434c693a453b8d671eb3028567196efe3862247b5 + 2189a607137658bd; + 97a48030370c33 + d090c54215 + abd6b3ad54efc9a38378c5b93bf4f2aad2605f + aee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed + a17d9633a5629dc6336820d8bcdee53caa4989a877fd040f523603f3dd + dd98b6ad547d14c2; + 54154f8f28523c03d4de + 160015 + "" + "" + "" + 8cd54796; + 7846b710ee72807a2219 + bfb474 + fd + "" + "" + 4eb0f5a5; + 71d891f24bb65d156325 + 9f9eb5 + "" + 3b + d6 + ed17ae0a; + 571ea629c54d57dd2d42 + f70800df9f + cbaca48b77dba189196d1ebba10b0467cb9fc2712a199e53 + 3fa9156308cdec3f768281e040a9b9a222bd689aef66f530 + a56c65d5ded200e4794f3478f6774dc80e78ebd4ab58a107 + 12c12c76eaf729d8; + 6ceb0c6b08ac8b0a2226 + 0c571b4a42 + bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b + 6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b + 5fc52790c2df7b9f044c3e6316146e03002f98398cedd18400504685c0 + 6cc3f23b70f9e36e; + 5337685a96ed65b9ac + a33852 + "" + "" + "" + b0ad3d08; + 7ef19b09c063c46f88 + de9fd4 + 1e + "" + "" + 97501f94; + 72d7b97e23e6eabdff + 3bcd21 + "" + 14 + 1a + 25f269c4; + 99268878dbf30f1dad + 89d4b9b120 + 12e4713df46795630e7952d22bb02d7100b8b649377d20a8 + f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b7 + 0d3a7ed00ed5d1408dc96af9770a20b7e9a64569ce57c57a + 48de48bb0f882042; + 0d30ce2f1fef6ef315 + d079839180 + 5da08da3aefc5f8584b7c5e617669c0f16e398 + 15d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c + 41f84b6002f879d39df0797e355cb3a57a3fe6fd635c0daec81ebc831f + 79c9b18e32ba64e1; +} + +tea-eax { + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + dd6dedcd5275f77b; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + 0601c82ec2fc3944; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + d7f75b8b18dabaab; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + 42 + 39a3b75cfe30c3e2; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794 + 846ecfa14a7130c9f137120634c9519848a877ff77bf7919 + 2a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + 0f7263dd0709bb15fa04b8a0a27fe19b40e69596e2f7797d + f6a7ce18a023f8e6; + 406a6136512061f7080cc07df0 + 591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c92690 + 29df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + ddfb3fac295c9dd9307d5d1464f7b9f9d318b0e3e08fdd6f753b17e248 + b9850b3a65c973e7; + 05e505da1435dc + "" + "" + "" + "" + dc9b34fb8f76a62c; + eaa7b1cc49ae1d + 50 + "" + "" + "" + a3f9e0e94be8cc0e; + c38201a894476b + "" + 3f + "" + "" + a34f5355471f105e; + 102b752eb95295 + "" + "" + 33 + ad + 53d51c56bd3a3ee2; + 966f27043eb621 + b7f65b000961040e + f2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215e + b57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215 + bd62aa1bd2f58df364ecf889d4ede278c68a786cfa817416 + 69a5bc7134f4df07; + abd6b3ad54efc9 + a38378c5b93bf4 + f2aad2605faee2b03fb648e27fff63102758fe + 2b69ac26afa3349829b94586306fed54154f8f28523c03d4de16001578 + 345be4b0614ed2b6cee8f1d10f45f48bd6733ffab61b6f5a4fb978b66a + 6e7e6f6f73563d4e; + 46b710ee72807a2219bf + "" + "" + "" + "" + 6eedc1098c543339; + b474fd71d891f24bb65d + 15 + "" + "" + "" + fb16881264b9b3b2; + 63259f9eb53b571ea629 + "" + c5 + "" + "" + 753bcc1f76e8e1d2; + 4d57dd2d42f70800df9f + "" + "" + cb + 1b + 3eea24f4c849250a; + aca48b77dba189196d1e + bba10b0467cb9fc2 + 712a199e533fa9156308cdec3f768281e040a9b9a222bd68 + 9aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb23 + 78cdf18395582eae53580e5c7509bf60c8726dece28af741 + 5be9c10405f17081; + 3bfa6a5cfb0bad7d9521 + 4ade49cb3b6f5f + e8368131115c037ba323fe1dc8151784873f0e + b5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88 + df834e65b1c814814d99f141cdbb8c2d201f47551689b9561f73df1a8d + 0b3460ba12e05a4a; + de9fd41e72d7b97e23 + "" + "" + "" + "" + 5532b9006b4c1a14; + e6eabdff3bcd211499 + 26 + "" + "" + "" + 9dc4ef03a759716f; + 8878dbf30f1dad89d4 + "" + b9 + "" + "" + abd0dd2ce24924b7; + b12012e4713df46795 + "" + "" + 63 + e0 + 5d2cc18653d26e6b; + 0e7952d22bb02d7100 + b8b649377d20a8f0 + 83455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d + 30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5 + a4321bcfe7f507eeced0ef16c59adb7010401f57d14a172a + bb947e016b25ce84; + e617669c0f16e39815 + d4e9cfce3ed1ec + df3d264a7f16cb16c2e815f422cdf0c8e30308 + be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed1 + 39f472084e8a3a053d250ae58c6a88e6313311f092a388c01ed590e3be + 62fab90c78f1e4d7; +} + +tea-gcm { + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + 104863c1b7cc0364; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + 6824d44998ad5200; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + 2be3fa8881eb57e1; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + 06 + 7ccc0eb121d76855; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794 + 846ecfa14a7130c9f137120634c9519848a877ff77bf7919 + 2a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + ccf001b2a76cd3c5568865d926c0c3c6289456233782bb6d + b4afc9476231f8db; + 406a6136512061f7080cc07df0 + 591d8fa2 + 1f2dd88374d8cde8e160ad + 10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9 + 556dc3cce065e32fd3631b31687e116db7a457f59687e62ec3b9e0f3713456edfd + c05e7bc1c66c2194; + 878731ebfedd4705e505da1435 + dceaa7b1cc49ae + 1d50c38201a894476b3f102b752eb952953396 + 6f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52eb + 65c59d689cade0038ba31ee851008842af4971efd43a6c0c83b662e9a7 + 53170fb69a4358c4; + fda19d0ccc520f + "" + "" + "" + "" + 353b4c25eb464d16; + 215eb57bb3a4f3 + eb + "" + "" + "" + f0b9141e092436ba; + bbb18ac6c95a97 + "" + a4 + "" + "" + 5a56e7ab195dff15; + 8030370c33d090 + "" + "" + c5 + 63 + 0ebbd392dd296be9; + 4215abd6b3ad54 + efc9a38378c5b93b + f4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26 + afa3349829b94586306fed54154f8f28523c03d4de160015 + 89fbccd054ce4e0e729a9348449702044abe666342d15dee + 09c94f26212a5c9c; + 7846b710ee7280 + 7a2219bf + b474fd71d891f24bb65d15 + 63259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebb + 62666b6deb78f4ca61a19405496b18f9af1e6c16c03eeafed378c6c14dc2760f87 + 5c37f56a50aad8ba; + a10b0467cb9fc2 + 712a199e533fa9 + 156308cdec3f768281e040a9b9a222bd689aef + 66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad + e44a6687f1516bda0c8403c0befbf7537a4cf036dcdcfd96e11d2dfda4 + 26338cb7a4856da3; + 7d95214ade49cb3b6f5f + "" + "" + "" + "" + d2ea2800e7d48c03; + e8368131115c037ba323 + fe + "" + "" + "" + 9f49f14465230250; + 1dc8151784873f0eb5b6 + "" + 47 + "" + "" + 1844b6087e8cca0f; + da6794c18b5337685a96 + "" + "" + ed + 8f + 7aa8c91ba90be3c4; + 65b9aca338527ef19b09 + c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89 + d4b9b12012e4713df46795630e7952d22bb02d7100b8b649 + d493f349ac86d68f2b5a119280b7e849a4fc67d29b952c51 + edf814101fdece49; + 377d20a8f083455b663e + 4ee1315f + 3c8f2aebfa921451dcd1af + 5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f + 72fde1faae8cceca80d4d76992f2636732bd05609713442fbf159576f9cb844e91 + c654365e3cecad77; + 16e39815d4e9cfce3ed1 + ecdf3d264a7f16 + cb16c2e815f422cdf0c8e30308be3c31e6bc58 + c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a87 + e28f18dcf71cfb49b094dac380189402100d4256169995d2f33dce3e77 + c86e61eec92dda36; + 4498ad0abef8bc4fcb + "" + "" + "" + "" + 4b7087b7ee345d6c; + 70e27e98ef1f0446b4 + 2f + "" + "" + "" + 9c586b9f2a4a8338; + b144d44b6d00f06dc1 + "" + 88 + "" + "" + f9c5a60277aba1ef; + d472a784e0c6f21195 + "" + "" + a3 + 01 + 0546d37e096d7325; + b9f4ae985511265feb + d11c164720eef9eb + 1c8dd0b00951f284649016ed00456331854bc78bf43966eb + 0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc + c579381ec4d7849aa0c7959d8b5fa316430a709bf6949cbb + 479c8f6f98bf9a02; + 2810d858cbbc8424d1 + 26b807e6 + daa089c3f9099c5ffb8241 + 73d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db + 6aa3da0c805ece511ebb54408d1529d4d5f993373fbba6425692a5a643b6e6cf5d + f2b2f11c0f79c16c; + 8f48af65f7cc9e3fb9 + 0e1721b730374f + fc9bc597f56ccbb2f294b38766fc69f6a9f2c0 + 945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f09 + ee503d12aef7e05140a33551f93a02eb6631e56e47a61f61b5357a4636 + 4f584686113ded23; +} + +tea-ocb1 { + 60d7bcda163547d348b7551195 + e77022907dd1dff7 + "" + "" + "" + 0282d13eb3775978; + dac5c9941d26d0c6eb14ad568f + 86edd1dc9268eeee + 53 + "" + "" + 9b0cdcfa8c04a747; + 3285a6ed810c9b689daaa9060d + 2d4b6003062365b0 + "" + a5 + 3b + cdfabcc04b5d33e6; + 4364c76c160f11896c4794846e + cfa14a7130c9f137 + "" + 120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d + 68cf0d4fc52e5f441683c80bdaac28743382b75271027f73 + 10e9f17c3d7446da; + 1f337f29549e6b0d27a4ba2340 + 85406a6136512061 + f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + 21635c6d62c9269029df3e6057acc87638f508046733d9ff + f5899357e4d68a1947927de3a88c20b0a372611945f68d3a + 172008bf86d64904; + 61cdbda3b3e9878731ebfedd47 + 05e505da1435dcea + "" + a7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 1871ca08dc9d4856d3181c8a16b9a5284e727cc4c21ee458e65a7ede72 + 400b866405f8cca1; + 21b7f65b000961040ef2f9b2fc + 5fa450727a9b542c + de52ebfda19d0ccc520f215eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b9 + 8845244bc553c66cbcd7398a529004c22b7bc44b8c12ee1cdae4b9964f + 11437ce8e831d965; + 3bf4f2aad2605f + aee2b03fb648e27f + "" + "" + "" + b24fea9cbe55c7cf; + ff63102758fe2b + 69ac26afa3349829 + b9 + "" + "" + 172ba721b939b9e3; + 4586306fed5415 + 4f8f28523c03d4de + "" + 16 + 56 + 8f3914c03d77623e; + 00157846b710ee + 72807a2219bfb474 + "" + fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d + 1f489e532c4895221fb87757559418ebdbb80731a4d433ca + aee9886723bcf8c2; + 42f70800df9fcb + aca48b77dba18919 + 6d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f76 + 8281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22 + 003b1897c5b5c2a68a1061f67ab282ba4f5bc1d5b69dff33 + d5d03c8ceb5dedad; + 260c571b4a42bb + 8fdb233bfa6a5cfb + "" + 0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc815178487 + 616c9b723ce2dbf6582926c0082396983b36136650dbe54d4034e80c81 + f272e48012ecedb1; + 3f0eb5b647da67 + 94c18b5337685a96 + ed65b9aca338527ef19b09c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012 + 61107d0d71b63c91fc60d6981a7b027175f951198ead98054f3c891a56 + f0b7270b5db81fec; + e4713df46795630e7952 + d22bb02d7100b8b6 + "" + "" + "" + 8ec34345774654fe; + 49377d20a8f083455b66 + 3e4ee1315f3c8f2a + eb + "" + "" + 9752407ae0186131; + fa921451dcd1af5813b7 + 0d30ce2f1fef6ef3 + "" + 15 + 81 + 1beb2958c9f181a1; + d0798391805da08da3ae + fc5f8584b7c5e617 + "" + 669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e8 + 76b4c7ff71df213ad4bacdd80c69f7e6dea704bfc63d27ba + dbdc98bafb6d3cd3; + 15f422cdf0c8e30308be + 3c31e6bc58c0b7ca + dcb658b970e47479a684b5aefa69a4cd52147ed12ca98698 + 1a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d4 + aff8e168c9ca00f7a3686535f2c3a87b87554ef97829cfdc + 5a0258fedb40c24f; + 4b6d00f06dc188d472a7 + 84e0c6f21195a3b9 + "" + f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00 + b9d9161aaec022635a134ed7847aec38d0c8903ef455fa741bf671369b + 625dbf5d69c3e31e; + 456331854bc78bf43966 + eb0cfa9138ddc399 + 08445608fe95e81c2533e31c9c1a9851bc2810 + d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f + 8a2521cc4a159578267a2501822161dab72ff8663eeb7c0216e8e372cb + 74098a7f405219bd; + 30cbb7f0e4a973a8cd + 190107314717a774 + "" + "" + "" + ea4da20a4cb1c61f; + 56f3ff669c732b58db + 8f48af65f7cc9e3f + b9 + "" + "" + 0db86f6d6832d301; + 0e1721b730374ffc9b + c597f56ccbb2f294 + "" + b3 + 32 + 7275eb9aee00342a; + 8766fc69f6a9f2c094 + 5ffd505003cc0cae + "" + 9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65 + d09b91ddba2620cd1a4a7fe88de8c22ef06be7a9b1627b4b + b37e8c04b73654d2; + cc1770a18cbfe6effd + 1ff6778554acf127 + 0485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b + 480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a + 962273e83ac507e225ed07a9fce44bf2dbaad409592ebd49 + 0a77a4eaf298a242; + 3e8128f8743d16687b + 7bb8deb9bd205b70 + "" + e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677 + 795b6ec2108ac4cbda8b87ede294541cfdb7240cfae8ff7a4d9a474ea5 + 798360c72cf9d7d0; + 508a15dde524af3e2b + ee0646541a42c2ec + ccb44d65bad397abfaf529ee41cf9a05c7efed + ef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a + f0d9c8a507a51d66a13e9cd477b177773ff6f94dbda67dbf07003162ab + 70ddae5e6ffa478f; +} + +tea-pmac1 { + 60d7bcda163547d348b7551195 + "" + 25bca2fe99e75c4b; + e77022907dd1dff7dac5c9941d + 26 + 5b87dc7b2acac1be; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0 + 6889c9fb6030676d; + a54364c76c160f11896c479484 + 6ecfa14a7130c9f137120634c9519848a877ff + 453581670da49ebe; + 77bf79192a5b50 + "" + 613c5d3427421aa4; + ade5d9cd739a3d + 1f + 39649926ad4cd68d; + 337f29549e6b0d + 27a4ba234085406a6136512061f7080cc07df0591d8fa21f + 24043405966f7f84; + 2dd88374d8cde8 + e160ad10997a21635c6d62c9269029df3e6057 + 8242433c45487ffe; + acc87638f508046733d9 + "" + f24ce66e0a3a63d2; + ff61cdbda3b3e9878731 + eb + 8bdfb1992aed4edf; + fedd4705e505da1435dc + eaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533 + ee6d2bd9a43a054a; + 966f27043eb621b7f65b + 000961040ef2f9b2fc5fa450727a9b542cde52 + 936eb156c9146198; + ebfda19d0ccc520f21 + "" + c33c9c35b8f3836e; + 5eb57bb3a4f3ebbbb1 + 8a + ac3f52785c36bf6f; + c6c95a97a48030370c + 33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260 + 1a935b87b899b277; + 5faee2b03fb648e27f + ff63102758fe2b69ac26afa3349829b9458630 + df79e3c4601f609a; +} + +tea-ocb3 { + 60d7bcda163547d348b7551195 + e77022907dd1 + "" + "" + "" + 50e56f25fe9fa75a; + dff7dac5c9941d26d0c6eb14ad + 568f86edd1dc + 92 + "" + "" + b018725e1da1fc14; + 68eeee533285a6ed810c9b689d + aaa9060d2d4b + "" + 60 + 94 + bce5f4718c762d22; + 03062365b0a54364c76c160f11 + 896c47 + "" + 94846ecfa14a7130c9f137120634c9519848a877ff77bf79 + f63c61926eb91517997efd1a280da07726f45280bd3d5893 + ce2fa9afb1a39afb; + 192a5b50ade5d9cd739a3d1f33 + 7f29549e6b + 0d27a4ba234085406a6136512061f7080cc07df0591d8fa2 + 1f2dd88374d8cde8e160ad10997a21635c6d62c9269029df + 3f60ebe2319bfad8b557bcd414b60e89212bbeea2a5c4373 + 74e2d32d1767921c; + 3e6057acc87638f508046733d9 + ff61cdbda3b3 + "" + e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a89447 + b04de9996b330715ff382cfec0333bfd66421410bf16459d12a0f28f53 + 38b0c98a1f1ec6da; + 6b3f102b752eb9529533966f27 + 043eb621b7f6 + 5b000961040ef2f9b2fc5fa450727a9b542cde + 52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c + f7e226026675e1adc5cf37952abccc77b8154368557b87ec40477620f8 + 44b45cf50973cb50; + 33d090c54215ab + d6b3ad54efc9 + "" + "" + "" + 1eb02bffdd9d7dc6; + a38378c5b93bf4 + f2aad2605fae + e2 + "" + "" + 58ee8252984db2d4; + b03fb648e27fff + 63102758fe2b + "" + 69 + d4 + 961e871fd84b5a74; + ac26afa3349829 + b94586 + "" + 306fed54154f8f28523c03d4de1600157846b710ee72807a + 0e6295372bd9df61b2ca8d2a383154e2c70fd3ca68805de6 + b8a6cce0dd7f6222; + 2219bfb474fd71 + d891f24bb6 + 5d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcb + aca48b77dba189196d1ebba10b0467cb9fc2712a199e533f + fd0562d5b003e68f0d1d72c4e082b87827f85ee88b52cd87 + 1e835d35eb0cd334; + a9156308cdec3f + 768281e040a9 + "" + b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb23 + 41c1cd96958e4f6ffaa16db2ec8a521140e548564fccdfb890ab8939f0 + 56271f56c7ea11ed; + 3bfa6a5cfb0bad + 7d95214ade49 + cb3b6f5fe8368131115c037ba323fe1dc81517 + 84873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c0 + fc1d24d91e4ab2c51590e2a94796bf4da4a50a6c07e20a40fb1981d17a + c8e3e3fd09cfb494; + 63c46f88de9fd41e72d7 + b97e23e6eabd + "" + "" + "" + b222e91b3dfc4b68; + ff3bcd211499268878db + f30f1dad89d4 + b9 + "" + "" + ceaecf08444b8cd3; + b12012e4713df4679563 + 0e7952d22bb0 + "" + 2d + a2 + d537e5734f7de7da; + 7100b8b649377d20a8f0 + 83455b + "" + 663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f + 4020ccd7a166229e19cd4c48b61701120098e7dad7780102 + ef64295063a916fa; + 1fef6ef315d079839180 + 5da08da3ae + fc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d + 264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0 + 07c0c12b3fad029d165bb6b6a9363c7699a27081a8aaf72b + f984336df824fe7e; + b7cadcb658b970e47479 + a684b5aefa69 + "" + a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446 + c19e2396ffc0dd7c73a0f53b39e90139179cefc32e75f8d50f5f627a39 + 2a57fec6502d09d9; + b42fb144d44b6d00f06d + c188d472a784 + e0c6f21195a3b9f4ae985511265febd11c1647 + 20eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0c + 3fb5c778395cfbfbd94d6707cb18520f9b95b101e5f1673248f37afb8f + 01ba4da3facd1ec8; + fa9138ddc399084456 + 08fe95e81c25 + "" + "" + "" + ef931af545c454ab; + 33e31c9c1a9851bc28 + 10d858cbbc84 + 24 + "" + "" + c24d1e102b084b5e; + d126b807e6daa089c3 + f9099c5ffb82 + "" + 41 + e8 + 3b28cf6d12081293; + 73d7634c04226f30cb + b7f0e4 + "" + a973a8cd190107314717a77456f3ff669c732b58db8f48af + 27a3f2e9c0dbf9ee78fe2eaea691734d96105ec04619032b + 552e65ed80338e08; + 65f7cc9e3fb90e1721 + b730374ffc + 9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003 + cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911 + 45aa335db92540c2bcd0ec28dd97d101c4e14776c4fd1d04 + fa2cf5a4f20122ef; + e32d65cc1770a18cbf + e6effd1ff677 + "" + 8554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b + 44c70463fafaed7e9b3de27cf5c92511a88eeaf9453b1da16914f9c61c + 62e9efc911c2b6d8; + 480aa3a4c84cef64f6 + c9b53bf8f957 + f4b03cf43e89957f9a3e8128f8743d16687b7b + b8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac84 + d848b6c4ea2e04b8599c41fa786fbac28cbef5ab4039415ca71d4678c7 + 19c2d53e7566afc7; +} + +tea-ocb3-mct { + 16 cb326883e2a7abc7; + 14 129631272316ca86; + 12 c0a6fdaab85e1578; + 10 112f7058a53b3c59; + 8 786b90684bfe1e77; + 6 842c674eb1cff4ed; + 4 f1319ace9cb4027c; + 16 fd0cc4fec30a; + 14 215b15aeab0e; + 12 f23528992843; + 10 48cacf15625e; + 8 74b0608cc983; + 6 d0dd11b11aa8; + 4 1960a6aa86d6; + 16 b9865f9f; + 14 6f09a6bc; + 12 b32b1dc6; + 10 13e1a721; + 8 b5aefa26; + 6 c2c46207; + 4 b0bf9065; +} diff --git a/symm/t/twofish.local b/symm/t/twofish.local new file mode 100644 index 00000000..1ec96057 --- /dev/null +++ b/symm/t/twofish.local @@ -0,0 +1,916 @@ +### Local tests for Twofish. + +twofish-cmac { + 60d7bcda163547d348b7551195 + "" + 754e3b8b4c2532dd6d26b8d2f84c5052; + e77022907dd1dff7dac5c9941d + 26 + 285e8d83398954587754b4811af4dab0; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1371206 + 8f5bfbfe9492043376e871ff2174ab5b; + 34c9519848a877ff77bf79192a + 5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8 + 1145ad608df01125e831efceb693c24b; + 8374d8cde8e160ad10997a21 + "" + 1406392a843cc373790cd8696e89d1ea; + 635c6d62c9269029df3e6057 + ac + 70ba3b7789c8bae0f1f51219e9730125; + c87638f508046733d9ff61cd + bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 6fa25a24102c74af333d7d00e814c926; + 21b7f65b000961040ef2f9b2 + fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5 + fa27b530c2b27564a3be2411d2eca2ff; + 4215abd6b3ad54ef + "" + ed98c8e1a4135fa9bbde6733062c0be7; + c9a38378c5b93bf4 + f2 + ebc7a731525279b9f3432af13aa735d1; + aad2605faee2b03f + b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219 + ad157b3ad3c9b514307a6075859baa83; + bfb474fd71d891f2 + 4bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9f + 2c6b7e9737106b483e1ca8497e995b5a; + c2712a199e533fa9156308cdec3f768281 + "" + 0b25455053592925387a5cab03aa3418; + e040a9b9a222bd689aef66f5306ceb0c6b + 08 + 795defa6334cf18ed76ffa59a9ef6500; + ac8b0a22260c571b4a42bb8fdb233bfa6a + 5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65 + 7a1639ba51eb2aeaf469d4980148378f; + b9aca338527ef19b09c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d + dabc6ab5c4f7051e8211bcafd27650f6; +} + +twofish-ccm { + 60d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9 + "" + "" + "" + b0c9e428; + 941d26d0c6eb14ad568f86edd1 + dc9268eeee533285a6ed81 + 0c + "" + "" + 68f3bf5a; + 9b689daaa9060d2d4b60030623 + 65b0a54364c76c160f1189 + "" + 6c + c6 + 30270248; + 4794846ecfa14a7130c9f13712 + 0634c9519848a877ff + 77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + f3d43c102dc21b52ba97431dbe9d96795b0c6d04920b5477e6ebf4706786e1bb6bf172fa749e9f62041c7b697875d4ee + 89a2a9f68c8a775f6d0ad66e43bfc2b5; + 05e505da1435dceaa7b1cc49ae + 1d50c38201a894476b + 3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0c + cc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad2605faee2b03fb6 + 13d35753fc8ea503aa2f2ce83e66c54c392aeab215aacd566043634da890cac0f81e7318c2640f2ccbdf691baf4e36e42d48a992a2 + 0337b188fc02b7868b5f6c0b9c462f44; + 48e27fff63102758fe2b69ac + 26afa3349829b94586306f + "" + "" + "" + f3b74c76; + ed54154f8f28523c03d4de16 + 00157846b710ee72807a22 + 19 + "" + "" + 0efb24c2; + bfb474fd71d891f24bb65d15 + 63259f9eb53b571ea629c5 + "" + 4d + fc + 2f1984e1; + 57dd2d42f70800df9fcbaca4 + 8b77dba189196d1ebb + a10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c57 + 1b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da67 + 6a399a08440ac7cb9d502c9f52a33d1df8ee9681bab13cfa2cae7aaeb82071cd7c99df8f768be5f910cf8db83e09f14c + 2ed58e267c0b2588e3910f0c31b961d3; + 94c18b5337685a96ed65b9ac + a338527ef19b09c063 + c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e + 7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d079839180 + 7aa91272a3c0c35156125064eb307c2e5bfe698266b7effff016afe64776bcc38d6965424f882285c418a92f480c24c59fcb2c1f79 + 6b3f9910b25e356ecfac4863fcee37d3; + 5da08da3aefc5f85 + 84b7c5e617669c0f16e398 + "" + "" + "" + b17a3a3d; + 15d4e9cfce3ed1ec + df3d264a7f16cb16c2e815 + f4 + "" + "" + d95d0468; + 22cdf0c8e30308be + 3c31e6bc58c0b7cadcb658 + "" + b9 + c7 + 0ef68941; + 70e47479a684b5ae + fa69a4cd52147ed12c + a986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae98 + 5511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608 + b0710f1564a118168643f2365349548ad8955fb798437ec62b9b3005d68ffc8e50ea0b92e3c7fe92c0c0660ec9945182 + e2d3128d41c1f5f53fd1727fe0b0b097; + fe95e81c2533e31c + 9c1a9851bc2810d858 + cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a7 + 7456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0c + fc551743341d475b9daee5768d456ab9a1e4c4156650b10689702560de27cc285a543e06e6f0b8e3e2868deba6ea47016e54a72bf5 + 169d69aa85a8d2806a324ea9568094fd; + ae9ce021a5f1fa4ffa91544485f1a1258b + 2b9b8f0911e32d65cc1770 + "" + "" + "" + eb7833ed; + a18cbfe6effd1ff6778554acf1270485b2 + 03a3c1c4c967c0a458cb94 + 8b + "" + "" + 2d96cd56; + dd409b687fa3a6827b480aa3a4c84cef64 + f6c9b53bf8f957f4b03cf4 + "" + 3e + 12 + 5739e99a; + 89957f9a3e8128f8743d16687b7bb8deb9 + bd205b70e04c091d20 + 5cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397 + abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107 + 9a42a39fcbb079b601c9a0169b11a7bda9592f85ee47a7cebf8be2dad4157356aedf18d3c792446f2439a0cf0d95e7f7 + 37724239996c480fc49e7e43a84458bc; + c8e7d715a92add9589d1f5c054b2d98351 + 4605ec590294a319b9 + 802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee + 1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44 + 0dd51ef8b16e3923be6906378e726f6e9d4b79b815fdad7282db135ee1d65a9b89f08c2976c77be0c5d76cdc530cfe077e71bfac9b + d086f21e917aa8b0152b51116a8d72af; +} + +twofish-eax { + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + 9c340a7f586dfd6561333d865d3be637; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + b49707150b501a9aeb08849a8ce835c5; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + 7c390db5bff614ee888d1b5a9d58a08f; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + 19 + 747cff93ab194812482ac265aae10c05; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794846ecfa14a7130c9 + f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7 + 080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61 + dd91fa89b463675215e5bf946e26d943bec9f16b85ab13386e59e241b8040179b9434123c3f18a91db1ca422e5ec4589 + 2516f3bef1bc5bc211b49bed94687265; + cdbda3b3e9878731ebfedd4705 + e505da1435dceaa7b1cc49ae1d50c3 + 8201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde + 52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260 + edf0e0b4ca907432f7c994c4d185aa3db5d998ad1911852793c31f1e08c8a0facb5b743188745f1f1f0a3b5cb459a49b6568ade9d9 + a8755cc0ba6d7951c1e462f3d7488839; + 5faee2b03fb648e27fff6310 + "" + "" + "" + "" + fabb71671ec2e89032276be01704ef69; + 2758fe2b69ac26afa3349829 + b9 + "" + "" + "" + 560eafd0ed251ac82b143a85f180b657; + 4586306fed54154f8f28523c + "" + 03 + "" + "" + 94fafa14c9819062fb631fb20d784aed; + d4de1600157846b710ee7280 + "" + "" + 7a + a8 + db105495b660dbd22506ea66be1d09d5; + 2219bfb474fd71d891f24bb6 + 5d1563259f9eb53b571ea629c54d57dd + 2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222 + bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe836813111 + 947c775e1a6deb3042c702a3600473796bebeb264ff0594b0352a85491239c812fa2f3c21d458e2b5b784625e5f8cc32 + 8e0728b45016d6178f32ee80773b72d0; + 5c037ba323fe1dc815178487 + 3f0eb5b647da6794c18b5337685a96 + ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89 + d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d + 1d131416240ea96f731942579422e18acb633d0429a46d31b64ff5f24f8ee6bb05769731eaf0da2725da3204f04820baf228831c09 + e21621e777b6283f5fbb2095f4d9a668; + 30ce2f1fef6ef315 + "" + "" + "" + "" + 52512330b00f2450fdfcb97d554ac098; + d0798391805da08d + a3 + "" + "" + "" + 58800f1e6613f646fe7e562590c3de9f; + aefc5f8584b7c5e6 + "" + 17 + "" + "" + 72cb0d5710a6a99ba7618544108409ad; + 669c0f16e39815d4 + "" + "" + e9 + 69 + 05f8ecb88a66f4a0289e5e3d04bddbe7; + cfce3ed1ecdf3d26 + 4a7f16cb16c2e815f422cdf0c8e30308 + be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98 + ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb1c8dd0b009 + 772117eeb7a3c0f1901d15bb4cd5aa2bbcc21c8900e9a590918c1278893bf93d6e10908d6aa0a3844de33ae47ef11fbf + 463ada14035a59434547a76404af4ee6; + 51f284649016ed00 + 456331854bc78bf43966eb0cfa9138 + ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb82 + 4173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3fb90e1721b730374ffc9bc5 + 5f7a453a5988894d4c010d0c1d61c46e0fdac102b82d40e60fd88fa2a733048be1adc091040977c1ce28b608f3b47f541316a51382 + b3e874d11f8b935d338bd549a4d8158a; + 97f56ccbb2f294b38766fc69f6a9f2c094 + "" + "" + "" + "" + 522cec98b8703b39bdef4b7b71100e69; + 5ffd505003cc0cae9ce021a5f1fa4ffa91 + 54 + "" + "" + "" + 9696c681b07c07a545c546a9698822fb; + 4485f1a1258b2b9b8f0911e32d65cc1770 + "" + a1 + "" + "" + e99931b41ebf63d52cb833b03c3f6ea4; + 8cbfe6effd1ff6778554acf1270485b203 + "" + "" + a3 + 53 + c4f447d9deadfeb7916af9eb906f838d; + c1c4c967c0a458cb948bdd409b687fa3a6 + 827b480aa3a4c84cef64f6c9b53bf8f9 + 57f4b03cf43e89957f9a3e8128f8743d16687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac + 8451399587011677508a15dde524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef340153 + ca3c5595f62889c4f242ac0da256bf103ca30908909139a4d43b0baa411a6fe47f8daf20b32bcba14f482f76b888265b + 041cf6ef9deec56c1bba923f276f8d75; + 9c51d2a90bbf7f1bfc338ab0ef5746ea8f + dcccd213e33f7e8a5718fd25014107 + c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7 + ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7ab + 1cc781e5396ac8524f32f3a2e1dd087ce19381548225aa1d043499e04890a78ba1c21cad856ff355265a9760b6f81ba5a9b34d275f + bb1cd29c56a26e0a9ef3fc8341f8f663; +} + +twofish-gcm { + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + 7e0c01ab8086fe01a7c940e3d5e4c825; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + 03cc1ef1b342e6882d46938c5583bcde; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + 922c01776999bb27557eaff4621e6542; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + 2d + 65db54152b66c0a4630723dad69c59fe; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794846ecfa14a7130c9 + f137120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7 + 080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61 + d2fd5ce98fff00c787eec5ba7c1428b7e298c61467e66996e9e34dd9f98e9dcb9e272339bcd0b5e261887f4a735d14e5 + bdee54527341a497d08ead912a0fd02b; + cdbda3b3e9878731ebfedd4705 + e505da1435dceaa7b1cc49ae + 1d50c38201a894476b3f102b752eb952953396 + 6f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33 + 7666e42e7493950c9783e8b919586b513c70b5ac09fcfcdd0a7199a12fded4b8c7499bc5803a2eb9c0e3934a4f42ff8fe32fad10326556567e + c341241121b63236496060eef63ffe36; + d090c54215abd6b3ad54efc9a3 + 8378c5b93bf4f2aad2605faee2b03f + b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee + 72807a2219bfb474fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b04 + 5f0cf7d078722238b7aaac66bf90a3a9761e66f896d956d9414d54a425e983126667ab8b776f1363fc275661175db1ee73d5529c59 + 0e29764305b7acf72af4b12db37fdb18; + 67cb9fc2712a199e533fa915 + "" + "" + "" + "" + dbe0886648906617f156b7749baf20d2; + 6308cdec3f768281e040a9b9 + a2 + "" + "" + "" + d250af0db768e3345e8cb717015d4481; + 22bd689aef66f5306ceb0c6b + "" + 08 + "" + "" + 11cea01fc59f767221b1d1f2d0143b96; + ac8b0a22260c571b4a42bb8f + "" + "" + db + 51 + 2d05a8a0ba680cee9cd48e338c8b48a9; + 233bfa6a5cfb0bad7d95214a + de49cb3b6f5fe8368131115c037ba323 + fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88de9fd41e72d7b97e23e6 + eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d7100b8b649377d20a8f08345 + 0499046ea761b7f3aa662f3bde9f5f0c37f36bb3fb0d364b585c4d2b0e4f4a66153fba1b366ac0c79439aeca1967adb8 + 8d5c3aac36d523729b5afb91924ee629; + 5b663e4ee1315f3c8f2aebfa + 921451dcd1af5813b70d30ce + 2f1fef6ef315d0798391805da08da3aefc5f85 + 84b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684 + ef0a5118e770a0a6ab603d85ad16ffecfc3e84c9c4e6390c6a658ba226d4f85ed42d57e886a1076bdd9ffae334371a545add74a74a6e59c7fb + 79064ad707bf5bb9f2443064d63635af; + b5aefa69a4cd52147ed12ca9 + 86981a874498ad0abef8bc4fcb70e2 + 7e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720ee + f9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d8 + 83eadff65bdc0a99b0c11b2414491643ef798658f9a4a2c78a46c89ca7476745450aaa0add25c28bd3c0eefeac9e7f19f3d95904d0 + 10317aaa71d95a323784406eecfc6621; + 58cbbc8424d126b8 + "" + "" + "" + "" + 4108dabb7754ccdf2f498097fe2493bb; + 07e6daa089c3f909 + 9c + "" + "" + "" + d2b1658dfe8f7e211bf9f3bee32064a8; + 5ffb824173d7634c + "" + 04 + "" + "" + ab2e2975c1c3b9bc07bb7b2c7a3f55fc; + 226f30cbb7f0e4a9 + "" + "" + 73 + 51 + 104b6be42e4ebbd2b94e5da48806507a; + a8cd190107314717 + a77456f3ff669c732b58db8f48af65f7 + cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0cae9ce021a5f1fa4ffa91 + 544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a458cb948bdd + 8b86c6c7e623c9e343ae7b1fa3d1eb8d38263234e881594a86fa291136d838ea2326aab6f331ed8241dc5632ab3dd10a + b0a96f29b83f2b02056bf2e94ac43147; + 409b687fa3a6827b + 480aa3a4c84cef64f6c9b53b + f8f957f4b03cf43e89957f9a3e8128f8743d16 + 687b7bb8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677508a15dde524af3e2bee0646541a42c2eccc + 96544d398a17314d02e7345a80062864904f86b8ba0280f29064775fb7669b6b2fc8f7e9b1fa6a213ec25349802826b9a6148ef2954df0a019 + c7a2ce4d1d3d9949eabebe7a572a5f7c; + b44d65bad397abfa + f529ee41cf9a05c7efedef3401539c + 51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c0 + 54b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70d17d4569eaff59a332ba58d5d5589bfe + ed9ebcc7d472e5707c7102b1cf72f2330419fbc2162a8d603f0bca3963eaf35992339cbe19b1525909be51f7a4cfebcb0b20efb5e7 + 11a34ad52fc2412ffde804945f7527de; + 079753ee1a957eb6d6699e6b7ea2725cb2 + "" + "" + "" + "" + bfce79cd62f6cd0cd7bb988245358c97; + dac07ecde95759ac46fee6dda7abc8ad68 + da + "" + "" + "" + 1582dba1ba23714f141583436dbb0af1; + ac90cfe22d2f1f2968cc42fa8b669ed3bb + "" + 35 + "" + "" + 7e202b58482cc68bee3ad6f7ccd6c034; + 42a9cf44bbc8c6254d980398bd94e66eb4 + "" + "" + 56 + 19 + e5560f7f46d1747af91a51b39fa2a553; + 3d405e51881e99027b8ab9aea3ccf860b0 + 009740763d96836c5f87b95460938de1 + 288c69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c3680 + 0d9645563a308ba60076817523bd2abf1261b089d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f + a86b53285f02553f8eea5475249f7d19cdd539a0a2544e883ae030bdab6c626b5a459a384171205e95534a8e5c6658e1 + 6fca68ddf9bfb6b8a06b44be4bb55eec; + 834a06148f302c3973accd56f6f24e3395 + 8b8c2e2352fd61e4fa8fec81 + 6ac861a8b33779f09e7a10fc02a8f48afa3080 + ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578c8ec4837898a92142b5b0677da1ac273117b45bcfff5d5f8b6fd + 25c9ca2752529fa0759c758d42f753af1a4ab5b3f036d585663ce2c886009a979951f8ea9e492a2175238be31f71aecb2a240e14be8873994e + 944a53fbe54197cb27d46c0f768fde88; + e2893232a9f81d14517ffae475f6b94a43 + a67b3d380d2f9aaafe2dd721c0095c + 8808847689211450ba8095ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785f + e426a5a0e80f678d404147842941feeffdc2eb44dc8c0d5e8f444f7f4e0c893959b74dc23a7bb40e7e0013e5150686d2301b43a15a + 365bec4034b390949b707acfee0545eb79e0b47d87cdb901af6c3e964a997fe8c0faa678fa214c8ec5887e250c0d3007b2f1e29a93 + 2fc6d2d214bcad3f502b9bf292029e1c; +} + +twofish-ocb1 { + 60d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9941d26d0c6 + "" + "" + "" + 8d1cfee1984c2e05a4a9b88de25d0b03; + eb14ad568f86edd1dc9268eeee + 533285a6ed810c9b689daaa9060d2d4b + 60 + "" + "" + 71a0344b8fa6bcb38a5dcd91fe1ea7f4; + 03062365b0a54364c76c160f11 + 896c4794846ecfa14a7130c9f1371206 + "" + 34 + 79 + 7ad05aa4fccea98135597fed29e12041; + c9519848a877ff77bf79192a5b + 50ade5d9cd739a3d1f337f29549e6b0d + "" + 27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a21635c6d62c9269029df3e + bd4d3d7b5c177d602a76b0d30f94b746925a97ac08dbed466c21f623133b3b4a07a0cb3122bb409131b91e4891b4ad23 + 8184dd419c0d7f3c10ae44312fdf5223; + 6057acc87638f508046733d9ff + 61cdbda3b3e9878731ebfedd4705e505 + da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb621b7f65b000961040ef2f9b2fc5f + a450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215abd6b3ad54 + 90126eb72fa9923afc3d8381c787206cc21e1c0310b3aed18859d30dcccbebf00a040d6dc4127e8993eabc5d302aea03 + 2b753135ff0238a472730691c382446b; + efc9a38378c5b93bf4f2aad260 + 5faee2b03fb648e27fff63102758fe2b + "" + 69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219bfb474fd71d891f24bb65d1563259f9e + 261413d3a72447a6d5ffce0583f1b4af32e7203b82f5d6e8686ab8c21873e4741a9dff70ab872edffdbe7a795a7b4b7f469f3a6de5 + eb7184fda3922f373e8bcd6ca37d4042; + b53b571ea629c54d57dd2d42f7 + 0800df9fcbaca48b77dba189196d1ebb + a10b0467cb9fc2712a199e533fa9156308cdec3f768281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b + 0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da67 + c7a8156ec4894b7015e422efd4f9030c74e9e217ff1f15c02897a105a5c154391dac634298996cc30a8b383964cee203325787172e + 646143dc04f96fe66f7b7e10e2d956c2; + 94c18b5337685a96ed65b9ac + a338527ef19b09c063c46f88de9fd41e + "" + "" + "" + 0298067ddb8e8ad3a35c06d9aaa23012; + 72d7b97e23e6eabdff3bcd21 + 1499268878dbf30f1dad89d4b9b12012 + e4 + "" + "" + 26caf5aed4068af4fcdbf0aab49387c5; + 713df46795630e7952d22bb0 + 2d7100b8b649377d20a8f083455b663e + "" + 4e + de + 147491a865a55479e7820b48d65cfe86; + e1315f3c8f2aebfa921451dc + d1af5813b70d30ce2f1fef6ef315d079 + "" + 8391805da08da3aefc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e303 + a9ba8b1b3a7f68575146960578aaec63e43366c7ae57e481739749d32bddde3c33c7b4c5e096c8c0a96e2cbf5adecd17 + 0eab7b499f15026215627b43e0b9c17a; + 08be3c31e6bc58c0b7cadcb6 + 58b970e47479a684b5aefa69a4cd5214 + 7ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9 + f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0cfa9138ddc39908 + 0dee60335c90fde30d3e167df72c778839a69219947fcafa74f9bc6c21e32904b4298c20484c010e3aee5a032e33d3c9 + 9a199af39e93cb1225d112e9c0f01d61; + 445608fe95e81c2533e31c9c + 1a9851bc2810d858cbbc8424d126b807 + "" + e6daa089c3f9099c5ffb824173d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db8f48af65f7cc9e3f + e2a3d6365b19a3761fd7be55731c5b3dbce322f528a322b8c5b24453cb6a22656c944a6e304f5b3fb4b7cffdd5f87e17fe54664f5e + 8af45bd468a49b9fb4af7dee23301b73; + b90e1721b730374ffc9bc597 + f56ccbb2f294b38766fc69f6a9f2c094 + 5ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6 + 778554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f + 9736fd0b0e9860bfb50e7d81301a7cec617bb1783e531a6708db5c790c5ffc287ce2e0f79d9a763bfff28182787061828fc2ed02fc + a00c4e76ab4c35fd8801455c627d2b9a; + 9a3e8128f8743d16 + 687b7bb8deb9bd205b70e04c091d205c + "" + "" + "" + 5f6ea6b0475400a164944c4a31a7547f; + dad9e9a79b1abf91 + b0851e5ca605ac845139958701167750 + 8a + "" + "" + e55c85fb82289b89250fd9f463b50b74; + 15dde524af3e2bee + 0646541a42c2ecccb44d65bad397abfa + "" + f5 + 98 + 82d904459d8811b4f0907618d0215d93; + 29ee41cf9a05c7ef + edef3401539c51d2a90bbf7f1bfc338a + "" + b0ef5746ea8fdcccd213e33f7e8a5718fd25014107c8e7d715a92add9589d1f5c054b2d983514605ec590294a319b980 + ff802a1e6113b0aac88c7a76f0338e3c95fc70c98801be1476af39a21b8bc15f5cfdf6c5643a716ab23091a187014eb2 + 3b80083b38ba73e4d4bab2799e93b59b; + 2068a9f891bc5ba5 + afabf8c3122d12d7ff3c41122d70d17d + 4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8ad68 + daac90cfe22d2f1f2968cc42fa8b669ed3bb3542a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9 + e0d20e66b71e3a13aedd139a71c5823d4fbee0d3a59e3c6414b562999b2948ee764542cfa3e846d92d2afc1f4374034d + 379db2c942b5aae433f382256bec565e; + aea3ccf860b00097 + 40763d96836c5f87b95460938de1288c + "" + 69d80ea12ff4bb5f069b8a2e86041c1b9fc214e9ca2186ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308b + be3aa26f73e11ecc3bc58559bcdb8b6e1fa772bf51cddfbcf1bda58fa77945b735ede1d04f1b0b3d9b732ce7852082e8ed98b9e63c + f5d209e5468ccc2e7988a33924daf18f; + a60076817523bd2a + bf1261b089d8f23a9c2835076a23faac + 2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4fa + 8fec816ac861a8b33779f09e7a10fc02a8f48afa3080ee119a52a9a817e4f2b94b0820cab383a8cffeea7c486315799dc875fba578 + 4bfc4201c557734332bd6162fcc0527136cd4ba9b3ea9dd265a3901551abc061862e1e1643a6fa6ae23cfce273204557d56e9e05ca + 8c085a22b651c7c3e54710d958570722; + c8ec4837898a92142b5b0677da1ac27311 + 7b45bcfff5d5f8b6fde2893232a9f81d + "" + "" + "" + cc01d47fcdd2ebfd7fc167351b89c25c; + 14517ffae475f6b94a43a67b3d380d2f9a + aafe2dd721c0095c8808847689211450 + ba + "" + "" + b604e266d82e05f040dfa3e55dca1544; + 8095ffab1eaadf66fd22ac1976063e113a + b61f813e28a1397a7974a1d7f4220c78 + "" + 5f + 68 + 87c774626abd1daca5cddd7c8dcba032; + e426a5a0e80f678d404147842941feeffd + c2eb44dc8c0d5e8f444f7f4e0c893959 + "" + b74dc23a7bb40e7e0013e5150686d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3 + 1f0dfa5f0c07208cf7d6e19d3b49c4335b63416bdf67eb3667d2642bcf8d8639f03c58ab865cce0f068b222eac1b3ad8 + f580549f5cce1fae5e1df61bfd49c97a; + ab6cf8556b7aa776945948d1b8834df219 + 6c92ec1718dcdeee0d52d9539726d281 + 0391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e737882cd09c2b9a80f34c0fde11c2481b11fc76bfa + 4dbf710a9e544e0c536ca1e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0 + 0efa3388b0f1344526b97696cd61d5974dd9339a37fdfd020ef6687384208deb99fb2c79a91bfcf57135ad36f60aeabd + 12c3060b6d5cd360d29a9f8ee62bb1cb; + a9aabb6c4e3c3554f8fb1ef61614c27029 + 5dfc0ca6551ca4bdb75359f91cb9d921 + "" + 056b7de74fc9a9b37154ce6c0b396179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3d + e2c8468063ab076373bf2c088a0a7a9acc80937ac2f29036a733b089f5214311bf48de59cca31051ad6eeca19f34154412d3e4acbb + 887f83fd9a8db0d28cd849e7ec0cd72d; + f6c2b3fac7cbcf96523d4723f91801325e + b8553236651c96788d73d192ee53b3f3 + ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b59ed034a867642d25d54756fa5c47f16f64b837 + bb4926214211a1c696ba172010abb433922a22d9fd881519165eb9d85197a21cc34ac0d5ae7be8dbf98e4ffed2cf6b1372a5aa47b5 + 6ce7de9f52ff4f4fc21a63423b6d084752f7f7dc7b4e2c7d781a7fc6c468d2ad5a694156b41e8033ef66a59606919b13435453b037 + ef0d9a53c0eadbb12806aab80d24d67d; +} + +twofish-pmac1 { + 60d7bcda163547d348b7551195 + "" + b9898ea028d9c1fb8192e585467aeff7; + e77022907dd1dff7dac5c9941d + 26 + d2547a3fa161edf4427ac2523c0e12f4; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0a54364c76c160f11896c4794846ecfa14a7130c9f1371206 + 629a79b85d3c132fa98b11bd247ae22a; + 34c9519848a877ff77bf79192a + 5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd8 + 78a88c6c5a799d4bf7276ef82681502b; + 8374d8cde8e160ad10997a21 + "" + 142ab85c8da67eb03c02351267ac528f; + 635c6d62c9269029df3e6057 + ac + 97ef82a6ab463b32b3c6de3b8858e703; + c87638f508046733d9ff61cd + bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 13e0efe3390a5696584ff6f095c9d866; + 21b7f65b000961040ef2f9b2 + fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c5 + 550b74f7ec72626368a2c58ce23bb008; + 4215abd6b3ad54ef + "" + f5dd9becdd3d3fbecc3dee067bb06ff6; + c9a38378c5b93bf4 + f2 + 51c108d4abf0343491d7ec7b74e35736; + aad2605faee2b03f + b648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219 + 1939152c1f82c19cc084a681ccdfbd3e; + bfb474fd71d891f2 + 4bb65d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9f + cdd10d315afef9594ea2d5be06e2e839; + c2712a199e533fa9156308cdec3f768281 + "" + ba9d8b182c751b42b9796bae5985d048; + e040a9b9a222bd689aef66f5306ceb0c6b + 08 + b504bad203181c0281e60284b1e93cd3; + ac8b0a22260c571b4a42bb8fdb233bfa6a + 5cfb0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b5337685a96ed65 + a23f906ae8ec8b99ff2344d2f22c953c; + b9aca338527ef19b09c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012e4713df46795630e7952d22bb02d + e8dc0b7392f193529199018bd6939012; +} + +twofish-ocb3 { + 60d7bcda163547d348b7551195 + e77022907dd1dff7dac5c9941d26 + "" + "" + "" + 7f2677b3ee050809f5e4a511a007024d; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9 + 06 + "" + "" + be8deddf16817c9c36d0fd7a1bfbee5e; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794846ecfa14a71 + "" + 30 + c0 + 08ab7139235abe4995e765e6a3cb82a8; + c9f137120634c9519848a877ff + 77bf79192a5b50ade5d9cd + "" + 739a3d1f337f29549e6b0d27a4ba234085406a6136512061f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + 47e1cc7b95ebd79869a91c2f062b8f2f577d56908f819cd78f55430e51223e2a5e37bac236601388a2b434c26aa8e7d2 + 5507241b459462d018dae1537cb30e8f; + 21635c6d62c9269029df3e6057 + acc87638f508046733d9ff61cd + bda3b3e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + 21b7f65b000961040ef2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a480 + 7f7357f93fcbabb0d2900992381ab4c3ace2bb992327a4d3d62ff63756b7ef734a0c2a6de3c4b01f76c3531ddd58edcf + 947dd27aa266be2c3d043571d4a14bb8; + 30370c33d090c54215abd6b3ad + 54efc9a38378c5b93bf4f2aad260 + "" + 5faee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed54154f8f28523c03d4de1600157846b710ee72807a2219 + baaa3ba12dcb88379960d13a294e16ae35fc238cca7e1ebd514ef33d2581ffff81c2860478a0ac7be7e2aec8b16ea37fe9e7df6f40 + b106b18872d92b55b10125092c07ca8a; + bfb474fd71d891f24bb65d1563 + 259f9eb53b571ea629c54d57dd2d + 42f70800df9fcbaca48b77dba189196d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f768281e040 + a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b6f5fe8368131115c + 3c67bd32c69ef6446bcf3b1ede303d6bc287368abaa84bbb26ead3899423d3099eca75c966044b67bafb88404ad639fae5857f3a6d + fc24dd4b1e6fdad71a59b7595a9e776e; + 037ba323fe1dc8151784873f + 0eb5b647da6794c18b5337685a96 + "" + "" + "" + 8b63ff209b6e7a0391301e76a4e0ea39; + ed65b9aca338527ef19b09c0 + 63c46f88de9fd41e72d7b97e23e6 + ea + "" + "" + a433659f0885976882831a3eb89eed53; + bdff3bcd211499268878dbf3 + 0f1dad89d4b9b12012e4713df467 + "" + 95 + 6d + 42fe65d65b86c7528a73f89a0ccdf4de; + 630e7952d22bb02d7100b8b6 + 49377d20a8f083455b663e + "" + 4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f + 674e1ecd1a10232c74655502be244c4fb08e1f727cb9131f2d2e46de210815b286fc3a75d4e3e1d50c82aa1453b3ca08 + fa220b12d50ce64f83a4884807d53c83; + 16e39815d4e9cfce3ed1ecdf + 3d264a7f16cb16c2e815f422cd + f0c8e30308be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a874498ad0abef8bc4f + cb70e27e98ef1f0446b42fb144d44b6d00f06dc188d472a784e0c6f21195a3b9f4ae985511265febd11c164720eef9eb + 8b26c53a06f4ce39b4f35da14098aa964a66b58d9d3385ac71fc9a4f31a6d2c69bd41780ef50785b2d4dc3c8d8de5ec3 + cb0b3d4ebe62634b66cb4c2f07a22bb8; + 1c8dd0b00951f284649016ed + 00456331854bc78bf43966eb0cfa + "" + 9138ddc39908445608fe95e81c2533e31c9c1a9851bc2810d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f + 45a59590b5218d7503eac38def06f24dde786aee5d74aa5818501d881b5955b3404fc92c02e671c95f03b6e10c875e43309e6314d8 + cc019326324d5f7a3ccfbf7fb4b4d007; + 30cbb7f0e4a973a8cd190107 + 314717a77456f3ff669c732b58db + 8f48af65f7cc9e3fb90e1721b730374ffc9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003cc0c + ae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65cc1770a18cbfe6effd1ff6778554acf1270485b203a3c1c4c967c0a4 + 601106b9872e22a419d22e77179a9d3f2f49259f77629473d6fe8cca0c7f80e94230ebb6c59aeaf544a26537b633cf3faca9afaba8 + 3eb85702ecc6a6208ff54e70c555d560; + 58cb948bdd409b68 + 7fa3a6827b480aa3a4c84cef64f6 + "" + "" + "" + 536ee06e4186eb19069cc7d2611bf1da; + c9b53bf8f957f4b0 + 3cf43e89957f9a3e8128f8743d16 + 68 + "" + "" + 7eb7549c58f0b3e0e900694ad60a34f2; + 7b7bb8deb9bd205b + 70e04c091d205cdad9e9a79b1abf + "" + 91 + a3 + c223c24ae40f10208b2d07032bf63b9c; + b0851e5ca605ac84 + 51399587011677508a15dd + "" + e524af3e2bee0646541a42c2ecccb44d65bad397abfaf529ee41cf9a05c7efedef3401539c51d2a90bbf7f1bfc338ab0 + 54484aa14a10c80f224295d4fdc98a962cb1a75c388282477149c9e2ad42cb7e19f72d20ecc895ffcdd94e5e184d4195 + 7790694ff014f4f29d8875d3483c665d; + ef5746ea8fdcccd2 + 13e33f7e8a5718fd25014107c8 + e7d715a92add9589d1f5c054b2d983514605ec590294a319b9802068a9f891bc5ba5afabf8c3122d12d7ff3c41122d70 + d17d4569eaff59a332ba58d5d5589bfe079753ee1a957eb6d6699e6b7ea2725cb2dac07ecde95759ac46fee6dda7abc8 + 873b418fb6d2d8038dd78169b110a57f6e6c58d917f938d27bf4cdb6a9a3e64b6782c71fa8001c22b4025ca054cdc7d4 + 80b7822cbc9921b5249460298edc38b0; + ad68daac90cfe22d + 2f1f2968cc42fa8b669ed3bb3542 + "" + a9cf44bbc8c6254d980398bd94e66eb4563d405e51881e99027b8ab9aea3ccf860b0009740763d96836c5f87b95460938de1288c69 + 0be9726d678b4975083f0553c995e8fe2e9397ae7b1099320daeff9b57e43d306f05d8806cda76754bde21c5aa5a038b2ecd64eff2 + 5fb04d39cbaf88ea62135df4d4661bf0; + d80ea12ff4bb5f06 + 9b8a2e86041c1b9fc214e9ca2186 + ddf1f6a7a3aa7e740da967828e3604b35b15ffaa6c36800d9645563a308ba60076817523bd2abf1261b089 + d8f23a9c2835076a23faac2cdd67771cc667a8331f0a170b66283e4f834a06148f302c3973accd56f6f24e33958b8c2e2352fd61e4 + dfbe4cf0fe2983dc101e9daf7d40770c0e6f679e56fe4947602c739ebf22782fb98932e02eb14973d825ea72fb651b6eafca5232ba + f92fdadf740caf2c4ea9666b7b052af2; + fa8fec816ac861a8b33779f09e7a10fc02 + a8f48afa3080ee119a52a9a817e4 + "" + "" + "" + 94c3b0151d59ed8a75ce295b97ca07f1; + f2b94b0820cab383a8cffeea7c48631579 + 9dc875fba578c8ec4837898a9214 + 2b + "" + "" + c88555532a51ef0d2999fd4b5964866b; + 5b0677da1ac273117b45bcfff5d5f8b6fd + e2893232a9f81d14517ffae475f6 + "" + b9 + bb + 2b2e9ebf26398af33b06cae0b1edf872; + 4a43a67b3d380d2f9aaafe2dd721c0095c + 8808847689211450ba8095 + "" + ffab1eaadf66fd22ac1976063e113ab61f813e28a1397a7974a1d7f4220c785fe426a5a0e80f678d404147842941feef + aa8ff926ae1d31b79b276ba4c6365896a9ac3f2b901cc6edbd98ef230dcb0c1175fc4cda3d3bab4b0cd0761ec60d1bf9 + 679ea4952bdb67410905826ee2164b91; + fdc2eb44dc8c0d5e8f444f7f4e0c893959 + b74dc23a7bb40e7e0013e51506 + 86d2301b43a15a84e81d7f5cedaa49e2414ebf47970e560475cff206877de69146acc3ab6cf8556b7aa776945948d1b8 + 834df2196c92ec1718dcdeee0d52d9539726d2810391b3f9d10c39b07ae8f08ce7cee4758a386a9943e97dedfbe61e73 + 5e3f9325ceafcf8ab3c05194722e13093f75502a722f012fcf67c3f78d905711e90f6f8b2cf11e4911fcf8a988c95fd9 + 715a5d5c308eb6c2d35c87de8c9bc36d; + 7882cd09c2b9a80f34c0fde11c2481b11f + c76bfa4dbf710a9e544e0c536ca1 + "" + e040f9ad5b04140d98edabe08485290a4d87d13b07398a1458c2c6b61dbdbc1cccada8c1a0a9aabb6c4e3c3554f8fb1ef61614c270 + f0849293c90d1b433a612900ab035a2359b4b0f40dae24c375d721449707bd4fbec89c934fc1610231b4171407dddf5d1cd26e4588 + e8b6889f97e92f7f90bd3367a6509d3c; + 295dfc0ca6551ca4bdb75359f91cb9d921 + 056b7de74fc9a9b37154ce6c0b39 + 6179d31f06a1dd5982cbc0d7cb23841da1ae8f4ae480cda98ad6cf2bacf6f9fd3f821330c43f3df6c2b3fa + c7cbcf96523d4723f91801325eb8553236651c96788d73d192ee53b3f3ebd66ddd98cedbe88e245de25b1593b70f8601562d90a9b5 + b1f9684caf6b151fdfcf38fcc9280ba779c2c5845bf3f3778eec5d7157134dd51c762d40ede77e70255f24e7cde7fb41c4e87aef3e + ae37ce3b049000e9a941f2e36ffc1b98; +} + +twofish-ocb3-mct { + 32 e9ce6449d92a77813175926010259b8e; + 28 a99db77f8c91ea244b94208509e02f0c; + 24 9a9b6ce8abdbf68c23f2ad13d9e46119; + 20 c8ef353c81e5742726a0128dd0a0f588; + 16 9c839aab8a36976e9d320767766e0aa6; + 12 7f3551b1eb590266c7d59ec6b2b14aa8; + 10 15fd08dea6427de5fb88050905d313b5; + 8 3615f256e0edc05af17b680d13534820; + 4 5a7c50c4e1263d509f2a263ed3587b2d; + 32 fbe280898f5232dfb0abd143; + 28 0816b9db96448972f47cc0b0; + 24 1fdbf8b9482aa91ef2975556; + 20 3292677aa668b89b179fc183; + 16 f1f605105a477669efdd0426; + 12 aa1d9537f7ae2c5c1729c147; + 10 e9b833d9ff3c9fc07b037282; + 8 138e0305a1520249dd678e0d; + 4 ebe50e379a1973275bca0d3d; + 32 0a09c938c2fa5dba; + 28 3e38764a044b24fb; + 24 fe6aa4380d1b161e; + 20 0e065914f197a226; + 16 31747d608f91f1a7; + 12 ffc71de4b3eec92d; + 10 fbe711df96a56989; + 8 b38b5c7577aea195; + 4 9530ea1063f27742; +} diff --git a/symm/t/xtea b/symm/t/xtea index be34740f..0cea08b6 100644 --- a/symm/t/xtea +++ b/symm/t/xtea @@ -68,3 +68,912 @@ xtea { c86c21d8c26dc291f662c8f2fe79b74b 0993d3b68c1d4a5d 2b4195c3d67e3f99; af4f4615c7c298639b9728251991419f 1e268f9e710313b5 2536ccd8fdfe30e1; } + +xtea-cmac { + 60d7bcda163547d348b7551195 + "" + 3fe52353f9b144ae; + e77022907dd1dff7dac5c9941d + 26 + 809e38cc35e3a145; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0 + 9e781632642b42cd; + a54364c76c160f11896c479484 + 6ecfa14a7130c9f137120634c9519848a877ff + 8d187ce6f32516ae; + 77bf79192a5b50 + "" + 12bacc0346a97c7f; + ade5d9cd739a3d + 1f + 76efca6f4ea48f3a; + 337f29549e6b0d + 27a4ba234085406a6136512061f7080cc07df0591d8fa21f + 390ba4bcc9d100f3; + 2dd88374d8cde8 + e160ad10997a21635c6d62c9269029df3e6057 + 666111e472d8cdfd; + acc87638f508046733d9 + "" + 2b1ff3b380aa5d5a; + ff61cdbda3b3e9878731 + eb + 85351b61c26c94cf; + fedd4705e505da1435dc + eaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533 + d8a892f0975b7e2c; + 966f27043eb621b7f65b + 000961040ef2f9b2fc5fa450727a9b542cde52 + 85b42005a520b9fc; + ebfda19d0ccc520f21 + "" + cf0f227f8b2a8b46; + 5eb57bb3a4f3ebbbb1 + 8a + a0cdc4acc3d77c92; + c6c95a97a48030370c + 33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260 + ac879bd822cf405d; + 5faee2b03fb648e27f + ff63102758fe2b69ac26afa3349829b9458630 + 295b9c45cd0a8bab; +} + +xtea-ccm { + 60d7bcda163547d348b7551195 + e77022 + "" + "" + "" + 254c9820; + 907dd1dff7dac5c9941d26d0c6 + eb14ad + 56 + "" + "" + 628ee141; + 8f86edd1dc9268eeee533285a6 + ed810c + "" + 9b + b6 + c68f9ba1; + 689daaa9060d2d4b6003062365 + b0a54364c7 + 6c160f11896c4794846ecfa14a7130c9f137120634c95198 + 48a877ff77bf79192a5b50ade5d9cd739a3d1f337f29549e + 5d451b7841e1046387c69f33e87585eedf30cd7df2d4a409 + ae1ade48fb30df53; + 6b0d27a4ba234085406a613651 + 2061f7080c + c07df0591d8fa21f2dd88374d8cde8e160ad10 + 997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbd + 587e64a45665ec8f4b0561f911c55bbddc89d3cb923ee2a79736d853f2 + 5dc68eee0336d9df; + a3b3e9878731eb + fedd47 + "" + "" + "" + e731a2e4; + 05e505da1435dc + eaa7b1 + cc + "" + "" + d61b3844; + 49ae1d50c38201 + a89447 + "" + 6b + 65 + ae5cf49a; + 3f102b752eb952 + 9533966f27 + 043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542c + de52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a + 5cda052e11d440e05347a5d392610573bb3382f451a23c91 + 6b984d2bbcde1308; + 97a48030370c33 + d090c54215 + abd6b3ad54efc9a38378c5b93bf4f2aad2605f + aee2b03fb648e27fff63102758fe2b69ac26afa3349829b94586306fed + e50f8051933dfcda7693161d2fa0885f455a610c3178d245abb8a7869c + 9bba96ded767f109; + 54154f8f28523c03d4de + 160015 + "" + "" + "" + 06d07295; + 7846b710ee72807a2219 + bfb474 + fd + "" + "" + 613f97d3; + 71d891f24bb65d156325 + 9f9eb5 + "" + 3b + 10 + 5262f065; + 571ea629c54d57dd2d42 + f70800df9f + cbaca48b77dba189196d1ebba10b0467cb9fc2712a199e53 + 3fa9156308cdec3f768281e040a9b9a222bd689aef66f530 + 728d0e2c1f92403c6c91538ca0a4d33c644728aa324d6fec + 3c8af92993cf2dfc; + 6ceb0c6b08ac8b0a2226 + 0c571b4a42 + bb8fdb233bfa6a5cfb0bad7d95214ade49cb3b + 6f5fe8368131115c037ba323fe1dc8151784873f0eb5b647da6794c18b + 758c2450b1b4b633088e2dacece8fce73bb681518bc74f24427f9cf532 + 768cfa0b76676f6e; + 5337685a96ed65b9ac + a33852 + "" + "" + "" + cd3b5fbe; + 7ef19b09c063c46f88 + de9fd4 + 1e + "" + "" + 77ec39fe; + 72d7b97e23e6eabdff + 3bcd21 + "" + 14 + 2b + 12bba0f1; + 99268878dbf30f1dad + 89d4b9b120 + 12e4713df46795630e7952d22bb02d7100b8b649377d20a8 + f083455b663e4ee1315f3c8f2aebfa921451dcd1af5813b7 + 84148214729971a1616f5a0a2261662e90ffe6ee853fc892 + cd1f0f55d1d79d35; + 0d30ce2f1fef6ef315 + d079839180 + 5da08da3aefc5f8584b7c5e617669c0f16e398 + 15d4e9cfce3ed1ecdf3d264a7f16cb16c2e815f422cdf0c8e30308be3c + fc533246fa0f63332c3806595c6a35a6cd0499e973ae7a0055755b4026 + ff6e5bc754f0adfd; +} + +xtea-eax { + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + 5f1c8be04844ffdf; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + 3fec55f722a3295e; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + 41b22cdc7a09818c; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + 68 + 8b0dec6244e10dd9; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794 + 846ecfa14a7130c9f137120634c9519848a877ff77bf7919 + 2a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + 4c3b648b0d6a0bf20eb496a17201e4fdd7581e1d34fe19f5 + 9576894304df1c06; + 406a6136512061f7080cc07df0 + 591d8fa21f2dd8 + 8374d8cde8e160ad10997a21635c6d62c92690 + 29df3e6057acc87638f508046733d9ff61cdbda3b3e9878731ebfedd47 + 495ac874eee71cda95fc4133cd8080514898385e542f44f56734ff86cf + 88db0b0c36963625; + 05e505da1435dc + "" + "" + "" + "" + b8d2cf3b4a2c82ed; + eaa7b1cc49ae1d + 50 + "" + "" + "" + ff304d08904cc45b; + c38201a894476b + "" + 3f + "" + "" + f13209350bfea66c; + 102b752eb95295 + "" + "" + 33 + 78 + 468ff217fd2da0e0; + 966f27043eb621 + b7f65b000961040e + f2f9b2fc5fa450727a9b542cde52ebfda19d0ccc520f215e + b57bb3a4f3ebbbb18ac6c95a97a48030370c33d090c54215 + c78a890e811a86978a2b944c7741ce0fc415aba17675e5be + 835bb97626f8a99e; + abd6b3ad54efc9 + a38378c5b93bf4 + f2aad2605faee2b03fb648e27fff63102758fe + 2b69ac26afa3349829b94586306fed54154f8f28523c03d4de16001578 + f8331f39c783a39406102bfdc1b324d0d4dabe5ec886474caef97209fd + e59ad9e764305aa4; + 46b710ee72807a2219bf + "" + "" + "" + "" + 603bc1df6ad3c9ef; + b474fd71d891f24bb65d + 15 + "" + "" + "" + bd337ef6bfba87bb; + 63259f9eb53b571ea629 + "" + c5 + "" + "" + 155833e773266034; + 4d57dd2d42f70800df9f + "" + "" + cb + 43 + d77a671a2285a75a; + aca48b77dba189196d1e + bba10b0467cb9fc2 + 712a199e533fa9156308cdec3f768281e040a9b9a222bd68 + 9aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb23 + ba08278e81846ceb38153d309a3a01a57f415763091e31cd + 9ec9746c66fea592; + 3bfa6a5cfb0bad7d9521 + 4ade49cb3b6f5f + e8368131115c037ba323fe1dc8151784873f0e + b5b647da6794c18b5337685a96ed65b9aca338527ef19b09c063c46f88 + b73f49154f95bdba7d27565233290a8b987df10315aa519dd927f2c862 + 8ebd3aa28ee4a127; + de9fd41e72d7b97e23 + "" + "" + "" + "" + 6139eca5fd2a9750; + e6eabdff3bcd211499 + 26 + "" + "" + "" + 8acc9b1625d62fb2; + 8878dbf30f1dad89d4 + "" + b9 + "" + "" + 9730f31424a77b48; + b12012e4713df46795 + "" + "" + 63 + 33 + 0db62109955eeea5; + 0e7952d22bb02d7100 + b8b649377d20a8f0 + 83455b663e4ee1315f3c8f2aebfa921451dcd1af5813b70d + 30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5 + 67acf23790a2997df84bf037c61118541471b963e076eb73 + b9d46f9d24d74df0; + e617669c0f16e39815 + d4e9cfce3ed1ec + df3d264a7f16cb16c2e815f422cdf0c8e30308 + be3c31e6bc58c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed1 + 913b6bc765751a1b774bdd80b81b54a40e6b943acb8d922c5ea0b049d3 + 32a223a2cb999dba; +} + +xtea-gcm { + 60d7bcda163547d348b7551195 + "" + "" + "" + "" + 965c89c5e9e67150; + e77022907dd1dff7dac5c9941d + 26 + "" + "" + "" + 4bc1d47c6aa62964; + d0c6eb14ad568f86edd1dc9268 + "" + ee + "" + "" + efbae174fcba078d; + ee533285a6ed810c9b689daaa9 + "" + "" + 06 + e8 + 3c4fa10c897f0762; + 0d2d4b6003062365b0a54364c7 + 6c160f11896c4794 + 846ecfa14a7130c9f137120634c9519848a877ff77bf7919 + 2a5b50ade5d9cd739a3d1f337f29549e6b0d27a4ba234085 + bffee89ad704bd37259e148b3c038bf2ee483ee7e15cddd8 + f679257dc029e7f1; + 406a6136512061f7080cc07df0 + 591d8fa2 + 1f2dd88374d8cde8e160ad + 10997a21635c6d62c9269029df3e6057acc87638f508046733d9ff61cdbda3b3e9 + 77f4d28e0589a98ab60a4c53cf2a34a4212aee7756a9ebf17f5c52b982ae5dc249 + d61642f2623b785f; + 878731ebfedd4705e505da1435 + dceaa7b1cc49ae + 1d50c38201a894476b3f102b752eb952953396 + 6f27043eb621b7f65b000961040ef2f9b2fc5fa450727a9b542cde52eb + f9d9ebb1b908d8d19893ce0bebb4c2b87110adc572425cf0d88b32fe2c + aa3002dffd42e3ff; + fda19d0ccc520f + "" + "" + "" + "" + dbafe92d502b3295; + 215eb57bb3a4f3 + eb + "" + "" + "" + 09ac92680bc52ddf; + bbb18ac6c95a97 + "" + a4 + "" + "" + 2845ab8e15cc6e83; + 8030370c33d090 + "" + "" + c5 + 3e + 8b12bd215589da19; + 4215abd6b3ad54 + efc9a38378c5b93b + f4f2aad2605faee2b03fb648e27fff63102758fe2b69ac26 + afa3349829b94586306fed54154f8f28523c03d4de160015 + 3dd971d21e1f273a18a156a12cc084d265744982a0bc84ee + e4bc1c22d869ce1f; + 7846b710ee7280 + 7a2219bf + b474fd71d891f24bb65d15 + 63259f9eb53b571ea629c54d57dd2d42f70800df9fcbaca48b77dba189196d1ebb + 35afbe16c12e4a71ee59d1e03479d82c240119d25d7f759298ca0c6a7261ec0df7 + 0e3afa58d945282f; + a10b0467cb9fc2 + 712a199e533fa9 + 156308cdec3f768281e040a9b9a222bd689aef + 66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb233bfa6a5cfb0bad + 91c7d3e6bdfdc99a009642e8586acdb300caf64ccfa844f823b02fb3a3 + 9d1d569032d47694; + 7d95214ade49cb3b6f5f + "" + "" + "" + "" + bf7b041a488d393e; + e8368131115c037ba323 + fe + "" + "" + "" + 41f54145c986899b; + 1dc8151784873f0eb5b6 + "" + 47 + "" + "" + 46aa574328fd728c; + da6794c18b5337685a96 + "" + "" + ed + fb + b2ae7fdba380ced8; + 65b9aca338527ef19b09 + c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89 + d4b9b12012e4713df46795630e7952d22bb02d7100b8b649 + 9b3dd3969b6367d11a17e2c10241592ea531ecf0445749eb + ee022fa7e8e3a576; + 377d20a8f083455b663e + 4ee1315f + 3c8f2aebfa921451dcd1af + 5813b70d30ce2f1fef6ef315d0798391805da08da3aefc5f8584b7c5e617669c0f + 4d32b3228edff4d5a35588331c433defeca851b5843150082ac23d5607ea06c83e + d1458ac231a4ac20; + 16e39815d4e9cfce3ed1 + ecdf3d264a7f16 + cb16c2e815f422cdf0c8e30308be3c31e6bc58 + c0b7cadcb658b970e47479a684b5aefa69a4cd52147ed12ca986981a87 + 8603545fa254880d1fceb81d2e937217d0edfd7f6713078624772c0f40 + fdc8cb8bc51a1533; + 4498ad0abef8bc4fcb + "" + "" + "" + "" + 9c3e0d53b5dca992; + 70e27e98ef1f0446b4 + 2f + "" + "" + "" + 04bf8339880c70bd; + b144d44b6d00f06dc1 + "" + 88 + "" + "" + fefa3ef4a95dbe20; + d472a784e0c6f21195 + "" + "" + a3 + 6c + 05da912be7dd7846; + b9f4ae985511265feb + d11c164720eef9eb + 1c8dd0b00951f284649016ed00456331854bc78bf43966eb + 0cfa9138ddc39908445608fe95e81c2533e31c9c1a9851bc + e72acc6e0d4490e549b969d30f773905cd6dc77f4ce77b22 + bb74ac6f9139c65f; + 2810d858cbbc8424d1 + 26b807e6 + daa089c3f9099c5ffb8241 + 73d7634c04226f30cbb7f0e4a973a8cd190107314717a77456f3ff669c732b58db + 9e8854454d108c12f18f23fb9a251b52e734a3221aea99928614d209d6e57a4305 + 44d67f8883a717e5; + 8f48af65f7cc9e3fb9 + 0e1721b730374f + fc9bc597f56ccbb2f294b38766fc69f6a9f2c0 + 945ffd505003cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f09 + ae7ea2a80ef6b2ec3b48f32be277ce5f984f50af216261f69bc2e65c2c + db4d7130d6508aa8; +} + +xtea-ocb1 { + 60d7bcda163547d348b7551195 + e77022907dd1dff7 + "" + "" + "" + 07bef2af9ee05be5; + dac5c9941d26d0c6eb14ad568f + 86edd1dc9268eeee + 53 + "" + "" + f772f8da875c6c16; + 3285a6ed810c9b689daaa9060d + 2d4b6003062365b0 + "" + a5 + 09 + ae03c614cee35738; + 4364c76c160f11896c4794846e + cfa14a7130c9f137 + "" + 120634c9519848a877ff77bf79192a5b50ade5d9cd739a3d + 667c317875cb68a2df759151a2340d3b90c7652e0a4cfcb1 + 93e92f0eef1160fb; + 1f337f29549e6b0d27a4ba2340 + 85406a6136512061 + f7080cc07df0591d8fa21f2dd88374d8cde8e160ad10997a + 21635c6d62c9269029df3e6057acc87638f508046733d9ff + 6f5d6a11b04cb03f734de83608675ca8cbb718197d5e6dae + e69dd7ec56052187; + 61cdbda3b3e9878731ebfedd47 + 05e505da1435dcea + "" + a7b1cc49ae1d50c38201a894476b3f102b752eb9529533966f27043eb6 + b2404d623b8994262e27a6e4e735dee18349a90f530e2a3f636d7c5f71 + ef92c0c42a1911fb; + 21b7f65b000961040ef2f9b2fc + 5fa450727a9b542c + de52ebfda19d0ccc520f215eb57bb3a4f3ebbb + b18ac6c95a97a48030370c33d090c54215abd6b3ad54efc9a38378c5b9 + b3c350ff78424273c10f103bbda2de658e037d6a35632be78052c55b53 + 131383b16016457a; + 3bf4f2aad2605f + aee2b03fb648e27f + "" + "" + "" + 7080c42bba62492f; + ff63102758fe2b + 69ac26afa3349829 + b9 + "" + "" + a4e5b67ccd313289; + 4586306fed5415 + 4f8f28523c03d4de + "" + 16 + 00 + d86ee5c4829dba67; + 00157846b710ee + 72807a2219bfb474 + "" + fd71d891f24bb65d1563259f9eb53b571ea629c54d57dd2d + 5a963f2a946fc9b06c9c9949f50eb85c1f3b54e009ea3950 + 43d5535e5b6fc923; + 42f70800df9fcb + aca48b77dba18919 + 6d1ebba10b0467cb9fc2712a199e533fa9156308cdec3f76 + 8281e040a9b9a222bd689aef66f5306ceb0c6b08ac8b0a22 + fc5846409e369e01687535ae0373827734da2375afab9ad3 + fb2bf11df41a072f; + 260c571b4a42bb + 8fdb233bfa6a5cfb + "" + 0bad7d95214ade49cb3b6f5fe8368131115c037ba323fe1dc815178487 + b7abf514a519880bcf9a1dd906236193181274945f26eeea26de9a4480 + 0a4c5b3dea189c9f; + 3f0eb5b647da67 + 94c18b5337685a96 + ed65b9aca338527ef19b09c063c46f88de9fd4 + 1e72d7b97e23e6eabdff3bcd211499268878dbf30f1dad89d4b9b12012 + abb5a85ee34c20c9ac26d5b84fb2079b949508c3a6c248aef713c7e3c8 + 66f1833b4afd2bd8; + e4713df46795630e7952 + d22bb02d7100b8b6 + "" + "" + "" + be24074b27f49059; + 49377d20a8f083455b66 + 3e4ee1315f3c8f2a + eb + "" + "" + ee190cc6ecad475c; + fa921451dcd1af5813b7 + 0d30ce2f1fef6ef3 + "" + 15 + bb + 5a83e24c3f3d84e9; + d0798391805da08da3ae + fc5f8584b7c5e617 + "" + 669c0f16e39815d4e9cfce3ed1ecdf3d264a7f16cb16c2e8 + a573de0fdef866acaa2ebd0be9a101af7f8e4ce6d9f33a2a + f3acd5608b4d8863; + 15f422cdf0c8e30308be + 3c31e6bc58c0b7ca + dcb658b970e47479a684b5aefa69a4cd52147ed12ca98698 + 1a874498ad0abef8bc4fcb70e27e98ef1f0446b42fb144d4 + acb6678d5dcfe7373c937b1b743ac60d7b039ee405cc184d + 426f814ef7af424d; + 4b6d00f06dc188d472a7 + 84e0c6f21195a3b9 + "" + f4ae985511265febd11c164720eef9eb1c8dd0b00951f284649016ed00 + 6b9981f8864012346d4faa801dc7d0aa35703d3a19fcbfd65c79509cc1 + 4b2c765518bd12b4; + 456331854bc78bf43966 + eb0cfa9138ddc399 + 08445608fe95e81c2533e31c9c1a9851bc2810 + d858cbbc8424d126b807e6daa089c3f9099c5ffb824173d7634c04226f + ade2fa7115805e2fe9464340d7b5a7c97c093ded512f5c7cec815ff278 + af6dddac99d6a024; + 30cbb7f0e4a973a8cd + 190107314717a774 + "" + "" + "" + 1bf75ebfe2f2c874; + 56f3ff669c732b58db + 8f48af65f7cc9e3f + b9 + "" + "" + b5e6cebf8f565eb4; + 0e1721b730374ffc9b + c597f56ccbb2f294 + "" + b3 + 18 + feee3b50ee01bc04; + 8766fc69f6a9f2c094 + 5ffd505003cc0cae + "" + 9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911e32d65 + e918a45ec5088f385ab211351a06495693bfb81dcd0d7749 + 9a6e716945055b00; + cc1770a18cbfe6effd + 1ff6778554acf127 + 0485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b + 480aa3a4c84cef64f6c9b53bf8f957f4b03cf43e89957f9a + b25ea7ed37027181c51ab3d374c9f2cf8dc6a5c275c93b11 + 6b72bcad7a2cc4a4; + 3e8128f8743d16687b + 7bb8deb9bd205b70 + "" + e04c091d205cdad9e9a79b1abf91b0851e5ca605ac8451399587011677 + 45c3c8686b2cd92247a8afc0ca13a832de78417abbd11d3e7a687bc4cc + 6247cc4284c11080; + 508a15dde524af3e2b + ee0646541a42c2ec + ccb44d65bad397abfaf529ee41cf9a05c7efed + ef3401539c51d2a90bbf7f1bfc338ab0ef5746ea8fdcccd213e33f7e8a + be2975c04e206859c47b5380c0e22d177563ce76c47538d89ae0be19f9 + 9cc636850cbc148f; +} + +xtea-pmac1 { + 60d7bcda163547d348b7551195 + "" + 5afaac6a8b1d8747; + e77022907dd1dff7dac5c9941d + 26 + 586ad5dfb39d35c5; + d0c6eb14ad568f86edd1dc9268 + eeee533285a6ed810c9b689daaa9060d2d4b6003062365b0 + e6a7ee16109f3b0d; + a54364c76c160f11896c479484 + 6ecfa14a7130c9f137120634c9519848a877ff + 320631d3f31f8840; + 77bf79192a5b50 + "" + eeb3c7cb0d072322; + ade5d9cd739a3d + 1f + 377efb6339f47074; + 337f29549e6b0d + 27a4ba234085406a6136512061f7080cc07df0591d8fa21f + 23266ff9052777ea; + 2dd88374d8cde8 + e160ad10997a21635c6d62c9269029df3e6057 + 387edca755c71aa8; + acc87638f508046733d9 + "" + f88c2d9748aafff6; + ff61cdbda3b3e9878731 + eb + 5502443fc2d9e373; + fedd4705e505da1435dc + eaa7b1cc49ae1d50c38201a894476b3f102b752eb9529533 + 722b4728cbe72195; + 966f27043eb621b7f65b + 000961040ef2f9b2fc5fa450727a9b542cde52 + c4d4788b5aaaba15; + ebfda19d0ccc520f21 + "" + df7b7666d395d55c; + 5eb57bb3a4f3ebbbb1 + 8a + 28c63dbfb924352f; + c6c95a97a48030370c + 33d090c54215abd6b3ad54efc9a38378c5b93bf4f2aad260 + df15e66620945a9d; + 5faee2b03fb648e27f + ff63102758fe2b69ac26afa3349829b9458630 + 5017699c228b645c; +} + +xtea-ocb3 { + 60d7bcda163547d348b7551195 + e77022907dd1 + "" + "" + "" + 5d2c01e9160963e2; + dff7dac5c9941d26d0c6eb14ad + 568f86edd1dc + 92 + "" + "" + f4290b5fa1095a3b; + 68eeee533285a6ed810c9b689d + aaa9060d2d4b + "" + 60 + 86 + a0258d79cfe3419c; + 03062365b0a54364c76c160f11 + 896c47 + "" + 94846ecfa14a7130c9f137120634c9519848a877ff77bf79 + 6610c7e7e150973b3af3229eaca70189ec0e13b564297b84 + 235c7f65cfd0cda9; + 192a5b50ade5d9cd739a3d1f33 + 7f29549e6b + 0d27a4ba234085406a6136512061f7080cc07df0591d8fa2 + 1f2dd88374d8cde8e160ad10997a21635c6d62c9269029df + ea5f7d5a908f059911b6b766f706d5f3c9a1b7d5b4d42065 + ba47585a0fa5b8d2; + 3e6057acc87638f508046733d9 + ff61cdbda3b3 + "" + e9878731ebfedd4705e505da1435dceaa7b1cc49ae1d50c38201a89447 + 1eb152c297208c394377db7669f0147c95b8fac5b1b8607d9584253b23 + d9340baabda4544b; + 6b3f102b752eb9529533966f27 + 043eb621b7f6 + 5b000961040ef2f9b2fc5fa450727a9b542cde + 52ebfda19d0ccc520f215eb57bb3a4f3ebbbb18ac6c95a97a48030370c + 67480201e5ad84d5c418b97dd662d14467346d3a41358000bcd2f70ad4 + c401dcec1ed2f580; + 33d090c54215ab + d6b3ad54efc9 + "" + "" + "" + 55b5295ceea5a2b0; + a38378c5b93bf4 + f2aad2605fae + e2 + "" + "" + 0f315886523d1ef8; + b03fb648e27fff + 63102758fe2b + "" + 69 + f9 + 6363d821109640b7; + ac26afa3349829 + b94586 + "" + 306fed54154f8f28523c03d4de1600157846b710ee72807a + 5d059d165b480d0bd30aa01fbc99b6c73bb78a97846f94e0 + dd5e7c83be0625ef; + 2219bfb474fd71 + d891f24bb6 + 5d1563259f9eb53b571ea629c54d57dd2d42f70800df9fcb + aca48b77dba189196d1ebba10b0467cb9fc2712a199e533f + 02ba51adcc2bb6ba3ab41756291366f14f0cb20893fa39a9 + 2b280bddba65b2fa; + a9156308cdec3f + 768281e040a9 + "" + b9a222bd689aef66f5306ceb0c6b08ac8b0a22260c571b4a42bb8fdb23 + cb82582817fa2dd3563bbc12c501093140d5df1fdbd0a319ad4f28cb28 + 0da5ea5b1a5fdddd; + 3bfa6a5cfb0bad + 7d95214ade49 + cb3b6f5fe8368131115c037ba323fe1dc81517 + 84873f0eb5b647da6794c18b5337685a96ed65b9aca338527ef19b09c0 + 2da5aa1294ef89aacc993ebd46ebec94a3feac279d392c27d92b0dbd30 + f2713c40cf993ef3; + 63c46f88de9fd41e72d7 + b97e23e6eabd + "" + "" + "" + f3501e0fcf27dbb5; + ff3bcd211499268878db + f30f1dad89d4 + b9 + "" + "" + 87b3dbbf4f9cc61d; + b12012e4713df4679563 + 0e7952d22bb0 + "" + 2d + c0 + 5618eb373dd8374f; + 7100b8b649377d20a8f0 + 83455b + "" + 663e4ee1315f3c8f2aebfa921451dcd1af5813b70d30ce2f + 99096150a0fe314a00a2336f097ad0f885f03c0b7cccd127 + a66de7481d491c0c; + 1fef6ef315d079839180 + 5da08da3ae + fc5f8584b7c5e617669c0f16e39815d4e9cfce3ed1ecdf3d + 264a7f16cb16c2e815f422cdf0c8e30308be3c31e6bc58c0 + 3a678d2a777b2eaa8d344e42aedd5e722ffef69ba742ae1a + d6bc78818c3bb4a3; + b7cadcb658b970e47479 + a684b5aefa69 + "" + a4cd52147ed12ca986981a874498ad0abef8bc4fcb70e27e98ef1f0446 + 85540182992781ca0104d764814e47ede859164af3405567d0c98bc7a0 + 8857121b533f8a6b; + b42fb144d44b6d00f06d + c188d472a784 + e0c6f21195a3b9f4ae985511265febd11c1647 + 20eef9eb1c8dd0b00951f284649016ed00456331854bc78bf43966eb0c + 8e650a51a481be8fa4eb4277832e68fef19321017bfcb05543ccbd1278 + b58014483ea856ce; + fa9138ddc399084456 + 08fe95e81c25 + "" + "" + "" + d6f325e74486f817; + 33e31c9c1a9851bc28 + 10d858cbbc84 + 24 + "" + "" + 1b88f76f4bff9de0; + d126b807e6daa089c3 + f9099c5ffb82 + "" + 41 + 8e + 1f85ea188d2fbe58; + 73d7634c04226f30cb + b7f0e4 + "" + a973a8cd190107314717a77456f3ff669c732b58db8f48af + 8ac6753b0a1edc91a058b5bd8cd84f6e2d84a066d3263392 + ea000b35774b2c35; + 65f7cc9e3fb90e1721 + b730374ffc + 9bc597f56ccbb2f294b38766fc69f6a9f2c0945ffd505003 + cc0cae9ce021a5f1fa4ffa91544485f1a1258b2b9b8f0911 + 96bdfd04ff0191407c3b1d881eb29c718dbfc93ef7852b24 + 3b4e8b97f9c055ea; + e32d65cc1770a18cbf + e6effd1ff677 + "" + 8554acf1270485b203a3c1c4c967c0a458cb948bdd409b687fa3a6827b + 99ab24f8a320e106aa12864be588d6af0459d33e27a7b0ab9dcad9de9d + f740e2e18cae5773; + 480aa3a4c84cef64f6 + c9b53bf8f957 + f4b03cf43e89957f9a3e8128f8743d16687b7b + b8deb9bd205b70e04c091d205cdad9e9a79b1abf91b0851e5ca605ac84 + 8d22fd98971cd873b0fab7bd557d5c4076eca3ed5f5acf7fa656bcc0b2 + 16899233ed9068ed; +} + +xtea-ocb3-mct { + 16 8cf53d7d6b43cdf1; + 14 5583f3a52de141d8; + 12 0b6565df07a02f3c; + 10 39da0a29f89a2699; + 8 24ea4af6cf4b09f8; + 6 6b4a51ac943cfa79; + 4 1f1b844caf0ddbae; + 16 6c4482111229; + 14 117519ba3a0f; + 12 ceb3bd9e235c; + 10 4d6a4907b3b5; + 8 6f7224393f2c; + 6 4629c2df66b4; + 4 c0ce4bd2a198; + 16 9ce1b811; + 14 b50aeacb; + 12 7c8e696b; + 10 8a6a0f17; + 8 f0422ae8; + 6 1c8cb415; + 4 b31dc24a; +} diff --git a/utils/advmodes b/utils/advmodes new file mode 100755 index 00000000..834771ce --- /dev/null +++ b/utils/advmodes @@ -0,0 +1,1033 @@ +#! /usr/bin/python + +from sys import argv, exit +from struct import unpack, pack +from itertools import izip +import catacomb as C + +R = C.FibRand(0) + +###-------------------------------------------------------------------------- +### Utilities. + +def combs(things, k): + ii = range(k) + n = len(things) + while True: + yield [things[i] for i in ii] + for j in xrange(k): + if j == k - 1: lim = n + else: lim = ii[j + 1] + i = ii[j] + 1 + if i < lim: + ii[j] = i + break + ii[j] = j + else: + return + +POLYMAP = {} + +def poly(nbits): + try: return POLYMAP[nbits] + except KeyError: pass + base = C.GF(0).setbit(nbits).setbit(0) + for k in xrange(1, nbits, 2): + for cc in combs(range(1, nbits), k): + p = base + sum(C.GF(0).setbit(c) for c in cc) + if p.irreduciblep(): POLYMAP[nbits] = p; return p + raise ValueError, nbits + +def prim(nbits): + ## No fancy way to do this: I'd need a much cleverer factoring algorithm + ## than I have in my pockets. + if nbits == 64: cc = [64, 4, 3, 1, 0] + elif nbits == 96: cc = [96, 10, 9, 6, 0] + elif nbits == 128: cc = [128, 7, 2, 1, 0] + elif nbits == 192: cc = [192, 15, 11, 5, 0] + elif nbits == 256: cc = [256, 10, 5, 2, 0] + else: raise ValueError, 'no field for %d bits' % nbits + p = C.GF(0) + for c in cc: p = p.setbit(c) + return p + +def Z(n): + return C.ByteString.zero(n) + +def mul_blk_gf(m, x, p): return ((C.GF.loadb(m)*x)%p).storeb((p.nbits + 6)/8) + +def with_lastp(it): + it = iter(it) + try: j = next(it) + except StopIteration: raise ValueError, 'empty iter' + lastp = False + while not lastp: + i = j + try: j = next(it) + except StopIteration: lastp = True + yield i, lastp + +def safehex(x): + if len(x): return hex(x) + else: return '""' + +def keylens(ksz): + sel = [] + if isinstance(ksz, C.KeySZSet): kk = ksz.set + elif isinstance(ksz, C.KeySZRange): kk = range(ksz.min, ksz.max, ksz.mod) + elif isinstance(ksz, C.KeySZAny): kk = range(64); sel = [0] + kk = list(kk); kk = kk[:] + n = len(kk) + while n and len(sel) < 4: + i = R.range(n) + n -= 1 + kk[i], kk[n] = kk[n], kk[i] + sel.append(kk[n]) + return sel + +def pad0star(m, w): + n = len(m) + if not n: r = w + else: r = (-len(m))%w + if r: m += Z(r) + return C.ByteString(m) + +def pad10star(m, w): + r = w - len(m)%w + if r: m += '\x80' + Z(r - 1) + return C.ByteString(m) + +def ntz(i): + j = 0 + while (i&1) == 0: i >>= 1; j += 1 + return j + +def blocks(x, w): + v, i, n = [], 0, len(x) + while n - i > w: + v.append(C.ByteString(x[i:i + w])) + i += w + return v, C.ByteString(x[i:]) + +EMPTY = C.bytes('') + +def blocks0(x, w): + v, tl = blocks(x, w) + if len(tl) == w: v.append(tl); tl = EMPTY + return v, tl + +def dummygen(bc): return [] + +CUSTOM = {} + +###-------------------------------------------------------------------------- +### RC6. + +class RC6Cipher (type): + def __new__(cls, w, r): + name = 'rc6-%d/%d' % (w, r) + me = type(name, (RC6Base,), {}) + me.name = name + me.r = r + me.w = w + me.blksz = w/2 + me.keysz = C.KeySZRange(me.blksz, 1, 255, 1) + return me + +def rotw(w): + return w.bit_length() - 1 + +def rol(w, x, n): + m0, m1 = C.MP(0).setbit(w - n) - 1, C.MP(0).setbit(n) - 1 + return ((x&m0) << n) | (x >> (w - n))&m1 + +def ror(w, x, n): + m0, m1 = C.MP(0).setbit(n) - 1, C.MP(0).setbit(w - n) - 1 + return ((x&m0) << (w - n)) | (x >> n)&m1 + +class RC6Base (object): + + ## Magic constants. + P400 = C.MP(0xb7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfef324e7738926cfbe5f4bf8d8d8c31d763da06) + Q400 = C.MP(0x9e3779b97f4a7c15f39cc0605cedc8341082276bf3a27251f86c6a11d0c18e952767f0b153d27b7f0347045b5bf1827f0188) + + def __init__(me, k): + + ## Build the magic numbers. + P = me.P400 >> (400 - me.w) + if P%2 == 0: P += 1 + Q = me.Q400 >> (400 - me.w) + if Q%2 == 0: Q += 1 + M = C.MP(0).setbit(me.w) - 1 + + ## Convert the key into words. + wb = me.w/8 + c = (len(k) + wb - 1)/wb + kb, ktl = blocks(k, me.w/8) + L = map(C.MP.loadl, kb + [ktl]) + assert c == len(L) + + ## Build the subkey table. + me.d = rotw(me.w) + n = 2*me.r + 4 + S = [(P + i*Q)&M for i in xrange(n)] + + ##for j in xrange(c): + ## print 'L[%3d] = %s' % (j, hex(L[j]).upper()[2:].rjust(2*wb, '0')) + ##for i in xrange(n): + ## print 'S[%3d] = %s' % (i, hex(S[i]).upper()[2:].rjust(2*wb, '0')) + + i = j = 0 + A = B = C.MP(0) + + for s in xrange(3*max(c, n)): + A = S[i] = rol(me.w, S[i] + A + B, 3) + B = L[j] = rol(me.w, L[j] + A + B, (A + B)%(1 << me.d)) + ##print 'S[%3d] = %s' % (i, hex(S[i]).upper()[2:].rjust(2*wb, '0')) + ##print 'L[%3d] = %s' % (j, hex(L[j]).upper()[2:].rjust(2*wb, '0')) + i = (i + 1)%n + j = (j + 1)%c + + ## Done. + me.s = S + + def encrypt(me, x): + M = C.MP(0).setbit(me.w) - 1 + a, b, c, d = map(C.MP.loadl, blocks0(x, me.blksz/4)[0]) + b = (b + me.s[0])&M + d = (d + me.s[1])&M + ##print 'B = %s' % (hex(b).upper()[2:].rjust(me.w/4, '0')) + ##print 'D = %s' % (hex(d).upper()[2:].rjust(me.w/4, '0')) + for i in xrange(2, 2*me.r + 2, 2): + t = rol(me.w, 2*b*b + b, me.d) + u = rol(me.w, 2*d*d + d, me.d) + a = (rol(me.w, a ^ t, u%(1 << me.d)) + me.s[i + 0])&M + c = (rol(me.w, c ^ u, t%(1 << me.d)) + me.s[i + 1])&M + ##print 'A = %s' % (hex(a).upper()[2:].rjust(me.w/4, '0')) + ##print 'C = %s' % (hex(c).upper()[2:].rjust(me.w/4, '0')) + a, b, c, d = b, c, d, a + a = (a + me.s[2*me.r + 2])&M + c = (c + me.s[2*me.r + 3])&M + ##print 'A = %s' % (hex(a).upper()[2:].rjust(me.w/4, '0')) + ##print 'C = %s' % (hex(c).upper()[2:].rjust(me.w/4, '0')) + return C.ByteString(a.storel(me.blksz/4) + b.storel(me.blksz/4) + + c.storel(me.blksz/4) + d.storel(me.blksz/4)) + + def decrypt(me, x): + M = C.MP(0).setbit(me.w) - 1 + a, b, c, d = map(C.MP.loadl, blocks0(x, me.blksz/4)) + c = (c - me.s[2*me.r + 3])&M + a = (a - me.s[2*me.r + 2])&M + for i in xrange(2*me.r + 1, 1, -2): + a, b, c, d = d, a, b, c + u = rol(me.w, 2*d*d + d, me.d) + t = rol(me.w, 2*b*b + b, me.d) + c = ror(me.w, (c - me.s[i + 1])&M, t%(1 << me.d)) ^ u + a = ror(me.w, (a - me.s[i + 0])&M, u%(1 << me.d)) ^ t + a = (a + s[2*me.r + 2])&M + c = (c + s[2*me.r + 3])&M + return C.ByteString(a.storel(me.blksz/4) + b.storel(me.blksz/4) + + c.storel(me.blksz/4) + d.storel(me.blksz/4)) + +for (w, r) in [(8, 16), (16, 16), (24, 16), (32, 16), + (32, 20), (48, 16), (64, 16), (96, 16), (128, 16), + (192, 16), (256, 16), (400, 16)]: + CUSTOM['rc6-%d/%d' % (w, r)] = RC6Cipher(w, r) + +###-------------------------------------------------------------------------- +### OMAC (or CMAC). + +def omac_masks(E): + blksz = E.__class__.blksz + p = poly(8*blksz) + z = Z(blksz) + L = E.encrypt(z) + m0 = mul_blk_gf(L, 2, p) + m1 = mul_blk_gf(m0, 2, p) + return m0, m1 + +def dump_omac(E): + blksz = E.__class__.blksz + m0, m1 = omac_masks(E) + print 'L = %s' % hex(E.encrypt(Z(blksz))) + print 'm0 = %s' % hex(m0) + print 'm1 = %s' % hex(m1) + for t in xrange(3): + print 'v%d = %s' % (t, hex(E.encrypt(C.MP(t).storeb(blksz)))) + print 'z%d = %s' % (t, hex(omac(E, t, ''))) + +def omac(E, t, m): + blksz = E.__class__.blksz + m0, m1 = omac_masks(E) + a = Z(blksz) + if t is not None: m = C.MP(t).storeb(blksz) + m + v, tl = blocks(m, blksz) + for x in v: a = E.encrypt(a ^ x) + r = blksz - len(tl) + if r == 0: + a = E.encrypt(a ^ tl ^ m0) + else: + pad = pad10star(tl, blksz) + a = E.encrypt(a ^ pad ^ m1) + return a + +def cmac(E, m): + if VERBOSE: dump_omac(E) + return omac(E, None, m), + +def cmacgen(bc): + return [(0,), (1,), + (3*bc.blksz,), + (3*bc.blksz - 5,)] + +###-------------------------------------------------------------------------- +### Counter mode. + +def ctr(E, m, c0): + blksz = E.__class__.blksz + y = C.WriteBuffer() + c = C.MP.loadb(c0) + while y.size < len(m): + y.put(E.encrypt(c.storeb(blksz))) + c += 1 + return C.ByteString(m) ^ C.ByteString(y)[:len(m)] + +###-------------------------------------------------------------------------- +### GCM. + +def gcm_mangle(x): + y = C.WriteBuffer() + for b in x: + b = ord(b) + bb = 0 + for i in xrange(8): + bb <<= 1 + if b&1: bb |= 1 + b >>= 1 + y.putu8(bb) + return C.ByteString(y) + +def gcm_mul(x, y): + w = len(x) + p = poly(8*w) + u, v = C.GF.loadl(gcm_mangle(x)), C.GF.loadl(gcm_mangle(y)) + z = (u*v)%p + return gcm_mangle(z.storel(w)) + +def gcm_pow(x, n): + w = len(x) + p = poly(8*w) + u = C.GF.loadl(gcm_mangle(x)) + z = pow(u, n, p) + return gcm_mangle(z.storel(w)) + +def gcm_ctr(E, m, c0): + y = C.WriteBuffer() + pre = c0[:-4] + c, = unpack('>L', c0[-4:]) + while y.size < len(m): + c += 1 + y.put(E.encrypt(pre + pack('>L', c))) + return C.ByteString(m) ^ C.ByteString(y)[:len(m)] + +def g(what, x, m, a0 = None): + n = len(x) + if a0 is None: a = Z(n) + else: a = a0 + i = 0 + for b in blocks0(m, n)[0]: + a = gcm_mul(a ^ b, x) + if VERBOSE: print '%s[%d] = %s -> %s' % (what, i, hex(b), hex(a)) + i += 1 + return a + +def gcm_pad(w, x): + return C.ByteString(x + Z(-len(x)%w)) + +def gcm_lens(w, a, b): + if w < 12: n = w + else: n = w/2 + return C.ByteString(C.MP(a).storeb(n) + C.MP(b).storeb(n)) + +def ghash(whata, whatb, x, a, b): + w = len(x) + ha = g(whata, x, gcm_pad(w, a)) + hb = g(whatb, x, gcm_pad(w, b)) + if a: + hc = gcm_mul(ha, gcm_pow(x, (len(b) + w - 1)/w)) ^ hb + if VERBOSE: print '%s || %s -> %s' % (whata, whatb, hex(hc)) + else: + hc = hb + return g(whatb, x, gcm_lens(w, 8*len(a), 8*len(b)), hc) + +def gcmenc(E, n, h, m, tsz = None): + w = E.__class__.blksz + x = E.encrypt(Z(w)) + if VERBOSE: print 'x = %s' % hex(x) + if len(n) + 4 == w: c0 = C.ByteString(n + pack('>L', 1)) + else: c0 = ghash('?', 'n', x, EMPTY, n) + if VERBOSE: print 'c0 = %s' % hex(c0) + y = gcm_ctr(E, m, c0) + t = ghash('h', 'y', x, h, y) ^ E.encrypt(c0) + return y, t + +def gcmdec(E, n, h, y, t): + w = E.__class__.blksz + x = E.encrypt(Z(w)) + if VERBOSE: print 'x = %s' % hex(x) + if len(n) + 4 == w: c0 = C.ByteString(n + pack('>L', 1)) + else: c0 = ghash('?', 'n', x, EMPTY, n) + if VERBOSE: print 'c0 = %s' % hex(c0) + m = gcm_ctr(E, y, c0) + tt = ghash('h', 'y', x, h, y) ^ E.encrypt(c0) + if t == tt: return m, + else: return None, + +def gcmgen(bc): + return [(0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1), + (bc.blksz, 3*bc.blksz, 3*bc.blksz), + (bc.blksz - 4, bc.blksz + 3, 3*bc.blksz + 9), + (bc.blksz - 1, 3*bc.blksz - 5, 3*bc.blksz + 5)] + +def gcm_mul_tests(nbits): + print 'gcm-mul%d {' % nbits + for i in xrange(64): + x = R.block(nbits/8) + y = R.block(nbits/8) + z = gcm_mul(x, y) + print ' %s\n %s\n %s;' % (hex(x), hex(y), hex(z)) + print '}' + +###-------------------------------------------------------------------------- +### CCM. + +def stbe(n, w): return C.MP(n).storeb(w) + +def ccm_fmthdr(blksz, n, hsz, msz, tsz): + b = C.WriteBuffer() + if blksz == 8: + q = blksz - len(n) - 1 + f = 0 + if hsz: f |= 0x40 + f |= (tsz - 1) << 3 + f |= q - 1 + b.putu8(f).put(n).put(stbe(msz, q)) + elif blksz == 16: + q = blksz - len(n) - 1 + f = 0 + if hsz: f |= 0x40 + f |= (tsz - 2)/2 << 3 + f |= q - 1 + b.putu8(f).put(n).put(stbe(msz, q)) + else: + q = blksz - len(n) - 2 + f0 = f1 = 0 + if hsz: f1 |= 0x80 + f0 |= tsz + f1 |= q + b.putu8(f0).putu8(f1).put(n).put(stbe(msz, q)) + b = C.ByteString(b) + if VERBOSE: print 'hdr = %s' % hex(b) + return b + +def ccm_fmtctr(blksz, n, i = 0): + b = C.WriteBuffer() + if blksz == 8 or blksz == 16: + q = blksz - len(n) - 1 + b.putu8(q - 1).put(n).put(stbe(i, q)) + else: + q = blksz - len(n) - 2 + b.putu8(0).putu8(q).put(n).put(stbe(i, q)) + b = C.ByteString(b) + if VERBOSE: print 'ctr = %s' % hex(b) + return b + +def ccmaad(b, h, blksz): + hsz = len(h) + if not hsz: pass + elif hsz < 0xfffe: b.putu16(hsz) + elif hsz <= 0xffffffff: b.putu16(0xfffe).putu32(hsz) + else: b.putu16(0xffff).putu64(hsz) + b.put(h); b.zero((-b.size)%blksz) + +def ccmenc(E, n, h, m, tsz = None): + blksz = E.__class__.blksz + if tsz is None: tsz = blksz + b = C.WriteBuffer() + b.put(ccm_fmthdr(blksz, n, len(h), len(m), tsz)) + ccmaad(b, h, blksz) + b.put(m); b.zero((-b.size)%blksz) + b = C.ByteString(b) + a = Z(blksz) + v, _ = blocks0(b, blksz) + i = 0 + for x in v: + a = E.encrypt(a ^ x) + if VERBOSE: + print 'b[%d] = %s' % (i, hex(x)) + print 'a[%d] = %s' % (i + 1, hex(a)) + i += 1 + y = ctr(E, a + m, ccm_fmtctr(blksz, n)) + return C.ByteString(y[blksz:]), C.ByteString(y[0:tsz]) + +def ccmdec(E, n, h, y, t): + blksz = E.__class__.blksz + tsz = len(t) + b = C.WriteBuffer() + b.put(ccm_fmthdr(blksz, n, len(h), len(y), tsz)) + ccmaad(b, h, blksz) + mm = ctr(E, t + Z(blksz - tsz) + y, ccm_fmtctr(blksz, n)) + u, m = C.ByteString(mm[0:tsz]), C.ByteString(mm[blksz:]) + b.put(m); b.zero((-b.size)%blksz) + b = C.ByteString(b) + a = Z(blksz) + v, _ = blocks0(b, blksz) + i = 0 + for x in v: + a = E.encrypt(a ^ x) + if VERBOSE: + print 'b[%d] = %s' % (i, hex(x)) + print 'a[%d] = %s' % (i + 1, hex(a)) + i += 1 + if u == a[:tsz]: return m, + else: return None, + +def ccmgen(bc): + bsz = bc.blksz + return [(bsz - 5, 0, 0, 4), (bsz - 5, 1, 0, 4), (bsz - 5, 0, 1, 4), + (bsz/2 + 1, 3*bc.blksz, 3*bc.blksz), + (bsz/2 + 1, 3*bc.blksz - 5, 3*bc.blksz + 5)] + +###-------------------------------------------------------------------------- +### EAX. + +def eaxenc(E, n, h, m, tsz = None): + if VERBOSE: + print 'k = %s' % hex(k) + print 'n = %s' % hex(n) + print 'h = %s' % hex(h) + print 'm = %s' % hex(m) + dump_omac(E) + if tsz is None: tsz = E.__class__.blksz + c0 = omac(E, 0, n) + y = ctr(E, m, c0) + ht = omac(E, 1, h) + yt = omac(E, 2, y) + if VERBOSE: + print 'c0 = %s' % hex(c0) + print 'ht = %s' % hex(ht) + print 'yt = %s' % hex(yt) + return y, C.ByteString((c0 ^ ht ^ yt)[:tsz]) + +def eaxdec(E, n, h, y, t): + if VERBOSE: + print 'k = %s' % hex(k) + print 'n = %s' % hex(n) + print 'h = %s' % hex(h) + print 'y = %s' % hex(y) + print 't = %s' % hex(t) + dump_omac(E) + c0 = omac(E, 0, n) + m = ctr(E, y, c0) + ht = omac(E, 1, h) + yt = omac(E, 2, y) + if VERBOSE: + print 'c0 = %s' % hex(c0) + print 'ht = %s' % hex(ht) + print 'yt = %s' % hex(yt) + if t == (c0 ^ ht ^ yt)[:len(t)]: return m, + else: return None, + +def eaxgen(bc): + return [(0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1), + (bc.blksz, 3*bc.blksz, 3*bc.blksz), + (bc.blksz - 1, 3*bc.blksz - 5, 3*bc.blksz + 5)] + +###-------------------------------------------------------------------------- +### PMAC. + +def ocb_masks(E): + blksz = E.__class__.blksz + p = poly(8*blksz) + x = C.GF(2); xinv = p.modinv(x) + z = Z(blksz) + L = E.encrypt(z) + Lxinv = mul_blk_gf(L, xinv, p) + Lgamma = 66*[L] + for i in xrange(1, len(Lgamma)): + Lgamma[i] = mul_blk_gf(Lgamma[i - 1], x, p) + return Lgamma, Lxinv + +def dump_ocb(E): + Lgamma, Lxinv = ocb_masks(E) + print 'L x^-1 = %s' % hex(Lxinv) + for i, lg in enumerate(Lgamma[:16]): + print 'L x^%d = %s' % (i, hex(lg)) + +def pmac1(E, m): + blksz = E.__class__.blksz + Lgamma, Lxinv = ocb_masks(E) + a = o = Z(blksz) + i = 0 + v, tl = blocks(m, blksz) + for x in v: + i += 1 + b = ntz(i) + o ^= Lgamma[b] + a ^= E.encrypt(x ^ o) + if VERBOSE: + print 'Z[%d]: %d -> %s' % (i, b, hex(o)) + print 'A[%d]: %s' % (i, hex(a)) + if len(tl) == blksz: a ^= tl ^ Lxinv + else: a ^= pad10star(tl, blksz) + return E.encrypt(a) + +def pmac2(E, m): + blksz = E.__class__.blksz + p = prim(8*blksz) + L = E.encrypt(Z(blksz)) + o = mul_blk_gf(L, 10, p) + a = Z(blksz) + v, tl = blocks(m, blksz) + for x in v: + a ^= E.encrypt(x ^ o) + o = mul_blk_gf(o, 2, p) + if len(tl) == blksz: a ^= tl ^ mul_blk_gf(o, 3, p) + else: a ^= pad10star(tl, blksz) ^ mul_blk_gf(o, 5, p) + return E.encrypt(a) + +def ocb3_masks(E): + Lgamma, _ = ocb_masks(E) + Lstar = Lgamma[0] + Ldollar = Lgamma[1] + return Lstar, Ldollar, Lgamma[2:] + +def dump_ocb3(E): + Lstar, Ldollar, Lgamma = ocb3_masks(E) + print 'L_* = %s' % hex(Lstar) + print 'L_$ = %s' % hex(Ldollar) + for i, lg in enumerate(Lgamma[:16]): + print 'L x^%d = %s' % (i, hex(lg)) + +def pmac3(E, m): + ## Note that `PMAC3' is /not/ a secure MAC. It depends on other parts of + ## OCB3 to prevent a rather easy linear-algebra attack. + blksz = E.__class__.blksz + Lstar, Ldollar, Lgamma = ocb3_masks(E) + a = o = Z(blksz) + i = 0 + v, tl = blocks0(m, blksz) + for x in v: + i += 1 + b = ntz(i) + o ^= Lgamma[b] + a ^= E.encrypt(x ^ o) + if VERBOSE: + print 'Z[%d]: %d -> %s' % (i, b, hex(o)) + print 'A[%d]: %s' % (i, hex(a)) + if tl: + o ^= Lstar + a ^= E.encrypt(pad10star(tl, blksz) ^ o) + if VERBOSE: + print 'Z[%d]: * -> %s' % (i, hex(o)) + print 'A[%d]: %s' % (i, hex(a)) + return a + +def pmac1_pub(E, m): + if VERBOSE: dump_ocb(E) + return pmac1(E, m), + +def pmacgen(bc): + return [(0,), (1,), + (3*bc.blksz,), + (3*bc.blksz - 5,)] + +###-------------------------------------------------------------------------- +### OCB. + +def ocb1enc(E, n, h, m, tsz = None): + ## This is OCB1.PMAC1 from Rogaway's `Authenticated-Encryption with + ## Associated-Data'. + blksz = E.__class__.blksz + if VERBOSE: dump_ocb(E) + Lgamma, Lxinv = ocb_masks(E) + if tsz is None: tsz = blksz + a = Z(blksz) + o = E.encrypt(n ^ Lgamma[0]) + if VERBOSE: print 'R = %s' % hex(o) + i = 0 + y = C.WriteBuffer() + v, tl = blocks(m, blksz) + for x in v: + i += 1 + b = ntz(i) + o ^= Lgamma[b] + a ^= x + if VERBOSE: + print 'Z[%d]: %d -> %s' % (i, b, hex(o)) + print 'A[%d]: %s' % (i, hex(a)) + y.put(E.encrypt(x ^ o) ^ o) + i += 1 + b = ntz(i) + o ^= Lgamma[b] + n = len(tl) + if VERBOSE: + print 'Z[%d]: %d -> %s' % (i, b, hex(o)) + print 'LEN = %s' % hex(C.MP(8*n).storeb(blksz)) + yfinal = E.encrypt(C.MP(8*n).storeb(blksz) ^ Lxinv ^ o) + cfinal = tl ^ yfinal[:n] + a ^= o ^ (tl + yfinal[n:]) + y.put(cfinal) + t = E.encrypt(a) + if h: t ^= pmac1(E, h) + return C.ByteString(y), C.ByteString(t[:tsz]) + +def ocb1dec(E, n, h, y, t): + ## This is OCB1.PMAC1 from Rogaway's `Authenticated-Encryption with + ## Associated-Data'. + blksz = E.__class__.blksz + if VERBOSE: dump_ocb(E) + Lgamma, Lxinv = ocb_masks(E) + a = Z(blksz) + o = E.encrypt(n ^ Lgamma[0]) + if VERBOSE: print 'R = %s' % hex(o) + i = 0 + m = C.WriteBuffer() + v, tl = blocks(y, blksz) + for x in v: + i += 1 + b = ntz(i) + o ^= Lgamma[b] + if VERBOSE: + print 'Z[%d]: %d -> %s' % (i, b, hex(o)) + print 'A[%d]: %s' % (i, hex(a)) + u = E.decrypt(x ^ o) ^ o + m.put(u) + a ^= u + i += 1 + b = ntz(i) + o ^= Lgamma[b] + n = len(tl) + if VERBOSE: + print 'Z[%d]: %d -> %s' % (i, b, hex(o)) + print 'LEN = %s' % hex(C.MP(8*n).storeb(blksz)) + yfinal = E.encrypt(C.MP(8*n).storeb(blksz) ^ Lxinv ^ o) + mfinal = tl ^ yfinal[:n] + a ^= o ^ (mfinal + yfinal[n:]) + m.put(mfinal) + u = E.encrypt(a) + if h: u ^= pmac1(E, h) + if t == u[:len(t)]: return C.ByteString(m), + else: return None, + +def ocb2enc(E, n, h, m, tsz = None): + ## For OCB2, it's important for security that n = log_x (x + 1) is large in + ## the field representations of GF(2^w) used -- in fact, we need more, that + ## i n (mod 2^w - 1) is large for i in {4, -3, -2, -1, 1, 2, 3, 4}. The + ## original paper lists the values for 64 and 128, but we support other + ## block sizes, so here's the result of the (rather large, in some cases) + ## computation. + ## + ## Block size log_x (x + 1) + ## + ## 64 9686038906114705801 + ## 96 63214690573408919568138788065 + ## 128 338793687469689340204974836150077311399 + ## 192 161110085006042185925119981866940491651092686475226538785 + ## 256 22928580326165511958494515843249267194111962539778797914076675796261938307298 + + blksz = E.__class__.blksz + if tsz is None: tsz = blksz + p = prim(8*blksz) + L = E.encrypt(n) + o = mul_blk_gf(L, 2, p) + a = Z(blksz) + v, tl = blocks(m, blksz) + y = C.WriteBuffer() + for x in v: + a ^= x + y.put(E.encrypt(x ^ o) ^ o) + o = mul_blk_gf(o, 2, p) + n = len(tl) + yfinal = E.encrypt(C.MP(8*n).storeb(blksz) ^ o) + cfinal = tl ^ yfinal[:n] + a ^= (tl + yfinal[n:]) ^ mul_blk_gf(o, 3, p) + y.put(cfinal) + t = E.encrypt(a) + if h: t ^= pmac2(E, h) + return C.ByteString(y), C.ByteString(t[:tsz]) + +def ocb2dec(E, n, h, y, t): + blksz = E.__class__.blksz + p = prim(8*blksz) + L = E.encrypt(n) + o = mul_blk_gf(L, 2, p) + a = Z(blksz) + v, tl = blocks(y, blksz) + m = C.WriteBuffer() + for x in v: + u = E.encrypt(x ^ o) ^ o + y.put(u) + a ^= u + o = mul_blk_gf(o, 2, p) + n = len(tl) + yfinal = E.encrypt(C.MP(8*n).storeb(blksz) ^ o) + mfinal = tl ^ yfinal[:n] + a ^= (mfinal + yfinal[n:]) ^ mul_blk_gf(o, 3, p) + m.put(mfinal) + u = E.encrypt(a) + if h: u ^= pmac2(E, h) + if t == u[:len(t)]: return C.ByteString(m), + else: return None, + +OCB3_STRETCH = { 4: ( 4, 17), + 8: ( 5, 25), + 12: ( 6, 33), + 16: ( 6, 8), + 24: ( 7, 40), + 32: ( 8, 1), + 48: ( 8, 80), + 64: ( 8, 176), + 96: ( 9, 160), + 128: ( 9, 352), + 200: (10, 192) } + +def ocb3nonce(E, n, tsz): + + ## Figure out how much we need to glue onto the nonce. This ends up being + ## [t mod w]_v || 0^p || 1 || N, where w is the block size in bits, t is + ## the tag length in bits, v = floor(log_2(w - 1)) + 1, and p = w - l(N) - + ## v - 1. But this is an annoying way to think about it because of the + ## byte misalignment. Instead, think of it as a byte-aligned prefix + ## encoding the tag and an `is the nonce full-length' flag, followed by + ## optional padding, and then the nonce: + ## + ## F || N if l(N) = w - f + ## F || 0^p || 1 || N otherwise + ## + ## where F is [t mod w]_v || 0^{f-v-1} || b; f = floor(log_2(w - 1)) + 2; + ## b is 1 if l(N) = w - f, or 0 otherwise; and p = w - f - l(N) - 1. + blksz = E.__class__.blksz + tszbits = min(C.MP(8*blksz - 1).nbits, 8) + fwd = tszbits/8 + 1 + f = 8*(tsz%blksz) << + 8*fwd - tszbits + + ## Form the augmented nonce. + nb = C.WriteBuffer() + nsz, nwd = len(n), blksz - fwd + if nsz == nwd: f |= 1 + nb.put(C.MP(f).storeb(fwd)) + if nsz < nwd: nb.zero(nwd - nsz - 1).putu8(1) + nb.put(n) + nn = C.ByteString(nb) + if VERBOSE: print 'aug-nonce = %s' % hex(nn) + + ## Calculate the initial offset. + split, shift = OCB3_STRETCH[blksz] + t2pw = C.MP(0).setbit(8*blksz) - 1 + lomask = (C.MP(0).setbit(split) - 1) + himask = ~lomask + top, bottom = nn&himask.storeb2c(blksz), C.MP.loadb(nn)&lomask + ktop = C.MP.loadb(E.encrypt(top)) + stretch = (ktop << 8*blksz) | (ktop ^ (ktop << shift)&t2pw) + o = (stretch >> 8*blksz - bottom).storeb(blksz) + if VERBOSE: + print 'stretch = %s' % hex(stretch.storeb(2*blksz)) + print 'Z[0] = %s' % hex(o) + + return o + +def ocb3enc(E, n, h, m, tsz = None): + blksz = E.__class__.blksz + if tsz is None: tsz = blksz + Lstar, Ldollar, Lgamma = ocb3_masks(E) + if VERBOSE: dump_ocb3(E) + + ## Set things up. + o = ocb3nonce(E, n, tsz) + a = C.ByteString.zero(blksz) + + ## Split the message into blocks. + i = 0 + y = C.WriteBuffer() + v, tl = blocks0(m, blksz) + for x in v: + i += 1 + b = ntz(i) + o ^= Lgamma[b] + a ^= x + if VERBOSE: + print 'Z[%d]: %d -> %s' % (i, b, hex(o)) + print 'A[%d]: %s' % (i, hex(a)) + y.put(E.encrypt(x ^ o) ^ o) + if tl: + o ^= Lstar + n = len(tl) + pad = E.encrypt(o) + a ^= pad10star(tl, blksz) + if VERBOSE: + print 'Z[%d]: * -> %s' % (i, hex(o)) + print 'A[%d]: %s' % (i, hex(a)) + y.put(tl ^ pad[0:n]) + o ^= Ldollar + t = E.encrypt(a ^ o) ^ pmac3(E, h) + return C.ByteString(y), C.ByteString(t[:tsz]) + +def ocb3dec(E, n, h, y, t): + blksz = E.__class__.blksz + tsz = len(t) + Lstar, Ldollar, Lgamma = ocb3_masks(E) + if VERBOSE: dump_ocb3(E) + + ## Set things up. + o = ocb3nonce(E, n, tsz) + a = C.ByteString.zero(blksz) + + ## Split the message into blocks. + i = 0 + m = C.WriteBuffer() + v, tl = blocks0(y, blksz) + for x in v: + i += 1 + b = ntz(i) + o ^= Lgamma[b] + if VERBOSE: + print 'Z[%d]: %d -> %s' % (i, b, hex(o)) + print 'A[%d]: %s' % (i, hex(a)) + u = E.encrypt(x ^ o) ^ o + m.put(u) + a ^= u + if tl: + o ^= Lstar + n = len(tl) + pad = E.encrypt(o) + if VERBOSE: + print 'Z[%d]: * -> %s' % (i, hex(o)) + print 'A[%d]: %s' % (i, hex(a)) + u = tl ^ pad[0:n] + m.put(u) + a ^= pad10star(u, blksz) + o ^= Ldollar + u = E.encrypt(a ^ o) ^ pmac3(E, h) + if t == u[:tsz]: return C.ByteString(m), + else: return None, + +def ocbgen(bc): + w = bc.blksz + return [(w, 0, 0), (w, 1, 0), (w, 0, 1), + (w, 0, 3*w), + (w, 3*w, 3*w), + (w, 0, 3*w + 5), + (w, 3*w - 5, 3*w + 5)] + +def ocb3gen(bc): + w = bc.blksz + return [(w - 2, 0, 0), (w - 2, 1, 0), (w - 2, 0, 1), + (w - 5, 0, 3*w), + (w - 3, 3*w, 3*w), + (w - 2, 0, 3*w + 5), + (w - 2, 3*w - 5, 3*w + 5)] + +def ocb3_mct(bc, ksz, tsz): + k = C.ByteString(C.WriteBuffer().zero(ksz - 4).putu32(8*tsz)) + E = bc(k) + n = C.MP(1) + nw = bc.blksz - 4 + cbuf = C.WriteBuffer() + for i in xrange(128): + s = C.ByteString.zero(i) + y, t = ocb3enc(E, n.storeb(nw), s, s, tsz); n += 1; cbuf.put(y).put(t) + y, t = ocb3enc(E, n.storeb(nw), EMPTY, s, tsz); n += 1; cbuf.put(y).put(t) + y, t = ocb3enc(E, n.storeb(nw), s, EMPTY, tsz); n += 1; cbuf.put(y).put(t) + _, t = ocb3enc(E, n.storeb(nw), C.ByteString(cbuf), EMPTY, tsz) + print hex(t) + +def ocb3_mct2(bc): + k = C.bytes('000102030405060708090a0b0c0d0e0f') + E = bc(k) + tsz = min(E.blksz, 32) + n = C.MP(1) + cbuf = C.WriteBuffer() + for i in xrange(128): + sbuf = C.WriteBuffer() + for j in xrange(i): sbuf.putu8(j) + s = C.ByteString(sbuf) + y, t = ocb3enc(E, n.storeb(2), s, s, tsz); n += 1; cbuf.put(y).put(t) + y, t = ocb3enc(E, n.storeb(2), EMPTY, s, tsz); n += 1; cbuf.put(y).put(t) + y, t = ocb3enc(E, n.storeb(2), s, EMPTY, tsz); n += 1; cbuf.put(y).put(t) + _, t = ocb3enc(E, n.storeb(2), C.ByteString(cbuf), EMPTY, tsz) + print hex(t) + +###-------------------------------------------------------------------------- +### Main program. + +class struct (object): + def __init__(me, **kw): + me.__dict__.update(kw) + +binarg = struct(mk = R.block, parse = C.bytes, show = safehex) +intarg = struct(mk = lambda x: x, parse = int, show = None) + +MODEMAP = { 'eax-enc': (eaxgen, 3*[binarg] + [intarg], eaxenc), + 'eax-dec': (dummygen, 4*[binarg], eaxdec), + 'ccm-enc': (ccmgen, 3*[binarg] + [intarg], ccmenc), + 'ccm-dec': (dummygen, 4*[binarg], ccmdec), + 'cmac': (cmacgen, [binarg], cmac), + 'gcm-enc': (gcmgen, 3*[binarg] + [intarg], gcmenc), + 'gcm-dec': (dummygen, 4*[binarg], gcmdec), + 'ocb1-enc': (ocbgen, 3*[binarg] + [intarg], ocb1enc), + 'ocb1-dec': (dummygen, 4*[binarg], ocb1dec), + 'ocb2-enc': (ocbgen, 3*[binarg] + [intarg], ocb2enc), + 'ocb2-dec': (dummygen, 4*[binarg], ocb2dec), + 'ocb3-enc': (ocb3gen, 3*[binarg] + [intarg], ocb3enc), + 'ocb3-dec': (dummygen, 4*[binarg], ocb3dec), + 'pmac1': (pmacgen, [binarg], pmac1_pub) } + +mode = argv[1] +if len(argv) == 3 and mode == 'gcm-mul': + VERBOSE = False + nbits = int(argv[2]) + gcm_mul_tests(nbits) + exit(0) +bc = None +for d in CUSTOM, C.gcprps: + try: bc = d[argv[2]] + except KeyError: pass + else: break +if bc is None: raise KeyError, argv[2] +if len(argv) == 5 and mode == 'ocb3-mct': + VERBOSE = False + ksz, tsz = int(argv[3]), int(argv[4]) + ocb3_mct(bc, ksz, tsz) + exit(0) +if len(argv) == 3 and mode == 'ocb3-mct2': + VERBOSE = False + ocb3_mct2(bc) + exit(0) +if len(argv) == 3: + VERBOSE = False + gen, argty, func = MODEMAP[mode] + if mode.endswith('-enc'): mode = mode[:-4] + print '%s-%s {' % (bc.name, mode) + for ksz in keylens(bc.keysz): + for argvals in gen(bc): + k = R.block(ksz) + args = [t.mk(a) for t, a in izip(argty, argvals)] + rets = func(bc(k), *args) + print ' %s' % safehex(k) + for t, a in izip(argty, args): + if t.show: print ' %s' % t.show(a) + for r, lastp in with_lastp(rets): + print ' %s%s' % (safehex(r), lastp and ';' or '') + print '}' +else: + VERBOSE = True + k = C.bytes(argv[3]) + gen, argty, func = MODEMAP[mode] + args = [t.parse(a) for t, a in izip(argty, argv[4:])] + rets = func(bc(k), *args) + for r in rets: + if r is None: print "X" + else: print hex(r) + +###----- That's all, folks -------------------------------------------------- diff --git a/utils/gcm-ref b/utils/gcm-ref new file mode 100755 index 00000000..ccbf4321 --- /dev/null +++ b/utils/gcm-ref @@ -0,0 +1,502 @@ +#! /usr/bin/python +### -*- coding: utf-8 -*- + +from sys import argv, exit + +import catacomb as C + +###-------------------------------------------------------------------------- +### Random utilities. + +def words(s): + """Split S into 32-bit pieces and report their values as hex.""" + return ' '.join('%08x' % C.MP.loadb(s[i:i + 4]) + for i in xrange(0, len(s), 4)) + +def words_64(s): + """Split S into 64-bit pieces and report their values as hex.""" + return ' '.join('%016x' % C.MP.loadb(s[i:i + 8]) + for i in xrange(0, len(s), 8)) + +def repmask(val, wd, n): + """Return a mask consisting of N copies of the WD-bit value VAL.""" + v = C.GF(val) + a = C.GF(0) + for i in xrange(n): a = (a << wd) | v + return a + +def combs(things, k): + """Iterate over all possible combinations of K of the THINGS.""" + ii = range(k) + n = len(things) + while True: + yield [things[i] for i in ii] + for j in xrange(k): + if j == k - 1: lim = n + else: lim = ii[j + 1] + i = ii[j] + 1 + if i < lim: + ii[j] = i + break + ii[j] = j + else: + return + +POLYMAP = {} + +def poly(nbits): + """ + Return the lexically first irreducible polynomial of degree NBITS of lowest + weight. + """ + try: return POLYMAP[nbits] + except KeyError: pass + base = C.GF(0).setbit(nbits).setbit(0) + for k in xrange(1, nbits, 2): + for cc in combs(range(1, nbits), k): + p = base + sum(C.GF(0).setbit(c) for c in cc) + if p.irreduciblep(): POLYMAP[nbits] = p; return p + raise ValueError, nbits + +def gcm_mangle(x): + """Flip the bits within each byte according to GCM's insane convention.""" + y = C.WriteBuffer() + for b in x: + b = ord(b) + bb = 0 + for i in xrange(8): + bb <<= 1 + if b&1: bb |= 1 + b >>= 1 + y.putu8(bb) + return y.contents + +def endswap_words_32(x): + """End-swap each 32-bit word of X.""" + x = C.ReadBuffer(x) + y = C.WriteBuffer() + while x.left: y.putu32l(x.getu32b()) + return y.contents + +def endswap_words_64(x): + """End-swap each 64-bit word of X.""" + x = C.ReadBuffer(x) + y = C.WriteBuffer() + while x.left: y.putu64l(x.getu64b()) + return y.contents + +def endswap_bytes(x): + """End-swap X by bytes.""" + y = C.WriteBuffer() + for ch in reversed(x): y.put(ch) + return y.contents + +def gfmask(n): + return C.GF(C.MP(0).setbit(n) - 1) + +def gcm_mul(x, y): + """Multiply X and Y according to the GCM rules.""" + w = len(x) + p = poly(8*w) + u, v = C.GF.loadl(gcm_mangle(x)), C.GF.loadl(gcm_mangle(y)) + z = (u*v)%p + return gcm_mangle(z.storel(w)) + +DEMOMAP = {} +def demo(func): + name = func.func_name + assert(name.startswith('demo_')) + DEMOMAP[name[5:].replace('_', '-')] = func + return func + +def iota(i = 0): + vi = [i] + def next(): vi[0] += 1; return vi[0] - 1 + return next + +###-------------------------------------------------------------------------- +### Portable table-driven implementation. + +def shift_left(x): + """Given a field element X (in external format), return X t.""" + w = len(x) + p = poly(8*w) + return gcm_mangle(C.GF.storel((C.GF.loadl(gcm_mangle(x)) << 1)%p)) + +def table_common(u, v, flip, getword, ixmask): + """ + Multiply U by V using table lookup; common for `table-b' and `table-l'. + + This matches the `simple_mulk_...' implementation in `gcm.c'. One-entry + per bit is the best we can manage if we want a constant-time + implementation: processing n bits at a time means we need to scan + (2^n - 1)/n times as much memory. + + * FLIP is a function (assumed to be an involution) on one argument X to + convert X from external format to table-entry format or back again. + + * GETWORD is a function on one argument B to retrieve the next 32-bit + chunk of a field element held in a `ReadBuffer'. Bits within a word + are processed most-significant first. + + * IXMASK is a mask XORed into table indices to permute the table so that + it's order matches that induced by GETWORD. + + The table is built such that tab[i XOR IXMASK] = U t^i. + """ + w = len(u); assert(w == len(v)) + a = C.ByteString.zero(w) + tab = [None]*(8*w) + for i in xrange(8*w): + print ';; %9s = %7s = %s' % ('utab[%d]' % i, 'u t^%d' % i, words(u)) + tab[i ^ ixmask] = flip(u) + u = shift_left(u) + v = C.ReadBuffer(v) + i = 0 + while v.left: + t = getword(v) + for j in xrange(32): + bit = (t >> 31)&1 + if bit: a ^= tab[i] + print ';; %6s = %d: a <- %s [%9s = %s]' % \ + ('v[%d]' % (i ^ ixmask), bit, words(a), + 'utab[%d]' % (i ^ ixmask), words(tab[i])) + i += 1; t <<= 1 + return flip(a) + +@demo +def demo_table_b(u, v): + """Big-endian table lookup.""" + return table_common(u, v, lambda x: x, lambda b: b.getu32b(), 0) + +@demo +def demo_table_l(u, v): + """Little-endian table lookup.""" + return table_common(u, v, endswap_words, lambda b: b.getu32l(), 0x18) + +###-------------------------------------------------------------------------- +### Implementation using 64×64->128-bit binary polynomial multiplication. + +_i = iota() +TAG_INPUT_U = _i() +TAG_INPUT_V = _i() +TAG_KPIECE_U = _i() +TAG_KPIECE_V = _i() +TAG_PRODPIECE = _i() +TAG_PRODSUM = _i() +TAG_PRODUCT = _i() +TAG_SHIFTED = _i() +TAG_REDCBITS = _i() +TAG_REDCFULL = _i() +TAG_REDCMIX = _i() +TAG_OUTPUT = _i() + +def split_gf(x, n): + n /= 8 + return [C.GF.loadb(x[i:i + n]) for i in xrange(0, len(x), n)] + +def join_gf(xx, n): + x = C.GF(0) + for i in xrange(len(xx)): x = (x << n) | xx[i] + return x + +def present_gf(x, w, n, what): + firstp = True + m = gfmask(n) + for i in xrange(0, w, 128): + print ';; %12s%c =%s' % \ + (firstp and what or '', + firstp and ':' or ' ', + ''.join([j < w + and ' 0x%s' % hex(((x >> j)&m).storeb(n/8)) + or '' + for j in xrange(i, i + 128, n)])) + firstp = False + +def present_gf_pclmul(tag, wd, x, w, n, what): + if tag != TAG_PRODPIECE: present_gf(x, w, n, what) + +def reverse(x, w): + return C.GF.loadl(x.storeb(w/8)) + +def rev32(x): + w = x.noctets + m_ffff = repmask(0xffff, 32, w/4) + m_ff = repmask(0xff, 16, w/2) + x = ((x&m_ffff) << 16) | ((x >> 16)&m_ffff) + x = ((x&m_ff) << 8) | ((x >> 8)&m_ff) + return x + +def rev8(x): + w = x.noctets + m_0f = repmask(0x0f, 8, w) + m_33 = repmask(0x33, 8, w) + m_55 = repmask(0x55, 8, w) + x = ((x&m_0f) << 4) | ((x >> 4)&m_0f) + x = ((x&m_33) << 2) | ((x >> 2)&m_33) + x = ((x&m_55) << 1) | ((x >> 1)&m_55) + return x + +def present_gf_mullp64(tag, wd, x, w, n, what): + if tag == TAG_PRODPIECE or tag == TAG_REDCFULL: + return + elif (wd == 128 or wd == 64) and TAG_PRODSUM <= tag <= TAG_PRODUCT: + y = x + elif (wd == 96 or wd == 192 or wd == 256) and \ + TAG_PRODSUM <= tag < TAG_OUTPUT: + y = x + else: + xx = x.storeb(w/8) + extra = len(xx)%8 + if extra: xx += C.ByteString.zero(8 - extra) + yb = C.WriteBuffer() + for i in xrange(len(xx), 0, -8): yb.put(xx[i - 8:i]) + y = C.GF.loadb(yb.contents) + present_gf(y, (w + 63)&~63, n, what) + +def present_gf_pmull(tag, wd, x, w, n, what): + if tag == TAG_PRODPIECE or tag == TAG_REDCFULL or tag == TAG_SHIFTED: + return + elif tag == TAG_INPUT_V or tag == TAG_KPIECE_V: + bx = C.ReadBuffer(x.storeb(w/8)) + by = C.WriteBuffer() + while bx.left: chunk = bx.get(8); by.put(chunk).put(chunk) + x = C.GF.loadb(by.contents) + w *= 2 + elif TAG_PRODSUM <= tag <= TAG_PRODUCT: + x <<= 1 + y = reverse(rev8(x), w) + present_gf(y, w, n, what) + +def poly64_mul_simple(u, v, presfn, wd, dispwd, mulwd, uwhat, vwhat): + """ + Multiply U by V, returning the product. + + This is the fallback long multiplication. + """ + + uw, vw = 8*len(u), 8*len(v) + + ## We start by carving the operands into 64-bit pieces. This is + ## straightforward except for the 96-bit case, where we end up with two + ## short pieces which we pad at the beginning. + if uw%mulwd: pad = (-uw)%mulwd; u += C.ByteString.zero(pad); uw += pad + if vw%mulwd: pad = (-uw)%mulwd; v += C.ByteString.zero(pad); vw += pad + uu = split_gf(u, mulwd) + vv = split_gf(v, mulwd) + + ## Report and accumulate the individual product pieces. + x = C.GF(0) + ulim, vlim = uw/mulwd, vw/mulwd + for i in xrange(ulim + vlim - 2, -1, -1): + t = C.GF(0) + for j in xrange(max(0, i - vlim + 1), min(vlim, i + 1)): + s = uu[ulim - 1 - i + j]*vv[vlim - 1 - j] + presfn(TAG_PRODPIECE, wd, s, 2*mulwd, dispwd, + '%s_%d %s_%d' % (uwhat, i - j, vwhat, j)) + t += s + presfn(TAG_PRODSUM, wd, t, 2*mulwd, dispwd, + '(%s %s)_%d' % (uwhat, vwhat, ulim + vlim - 2 - i)) + x += t << (mulwd*i) + presfn(TAG_PRODUCT, wd, x, uw + vw, dispwd, '%s %s' % (uwhat, vwhat)) + + return x + +def poly64_mul_karatsuba(u, v, klimit, presfn, wd, + dispwd, mulwd, uwhat, vwhat): + """ + Multiply U by V, returning the product. + + If the length of U and V is at least KLIMIT, and the operands are otherwise + suitable, then do Karatsuba--Ofman multiplication; otherwise, delegate to + `poly64_mul_simple'. + """ + w = 8*len(u) + + if w < klimit or w != 8*len(v) or w%(2*mulwd) != 0: + return poly64_mul_simple(u, v, presfn, wd, dispwd, mulwd, uwhat, vwhat) + + hw = w/2 + u0, u1 = u[:hw/8], u[hw/8:] + v0, v1 = v[:hw/8], v[hw/8:] + uu, vv = u0 ^ u1, v0 ^ v1 + + presfn(TAG_KPIECE_U, wd, C.GF.loadb(uu), hw, dispwd, '%s*' % uwhat) + presfn(TAG_KPIECE_V, wd, C.GF.loadb(vv), hw, dispwd, '%s*' % vwhat) + uuvv = poly64_mul_karatsuba(uu, vv, klimit, presfn, wd, dispwd, mulwd, + '%s*' % uwhat, '%s*' % vwhat) + + presfn(TAG_KPIECE_U, wd, C.GF.loadb(u0), hw, dispwd, '%s0' % uwhat) + presfn(TAG_KPIECE_V, wd, C.GF.loadb(v0), hw, dispwd, '%s0' % vwhat) + u0v0 = poly64_mul_karatsuba(u0, v0, klimit, presfn, wd, dispwd, mulwd, + '%s0' % uwhat, '%s0' % vwhat) + + presfn(TAG_KPIECE_U, wd, C.GF.loadb(u1), hw, dispwd, '%s1' % uwhat) + presfn(TAG_KPIECE_V, wd, C.GF.loadb(v1), hw, dispwd, '%s1' % vwhat) + u1v1 = poly64_mul_karatsuba(u1, v1, klimit, presfn, wd, dispwd, mulwd, + '%s1' % uwhat, '%s1' % vwhat) + + uvuv = uuvv + u0v0 + u1v1 + presfn(TAG_PRODSUM, wd, uvuv, w, dispwd, '%s!%s' % (uwhat, vwhat)) + + x = u1v1 + (uvuv << hw) + (u0v0 << w) + presfn(TAG_PRODUCT, wd, x, 2*w, dispwd, '%s %s' % (uwhat, vwhat)) + return x + +def poly64_common(u, v, presfn, dispwd = 32, mulwd = 64, redcwd = 32, + klimit = 256): + """ + Multiply U by V using a primitive 64-bit binary polynomial mutliplier. + + Such a multiplier exists as the appallingly-named `pclmul[lh]q[lh]qdq' on + x86, and as `vmull.p64'/`pmull' on ARM. + + Operands arrive in a `register format', which is a byte-swapped variant of + the external format. Implementations differ on the precise details, + though. + """ + + ## We work in two main phases: first, calculate the full double-width + ## product; and, second, reduce it modulo the field polynomial. + + w = 8*len(u); assert(w == 8*len(v)) + p = poly(w) + presfn(TAG_INPUT_U, w, C.GF.loadb(u), w, dispwd, 'u') + presfn(TAG_INPUT_V, w, C.GF.loadb(v), w, dispwd, 'v') + + ## So, on to the first part: the multiplication. + x = poly64_mul_karatsuba(u, v, klimit, presfn, w, dispwd, mulwd, 'u', 'v') + + ## Now we have to shift everything up one bit to account for GCM's crazy + ## bit ordering. + y = x << 1 + if w == 96: y >>= 64 + presfn(TAG_SHIFTED, w, y, 2*w, dispwd, 'y') + + ## Now for the reduction. + ## + ## Our polynomial has the form p = t^d + r where r = SUM_{0<=i= m, needs reduction; but + ## y_i t^{ni} = y_i r t^{n(i-m)}, so we just multiply the top half by r and + ## add it to the bottom half. This all depends on r_i = 0 for all i >= + ## n/2. We process each nonzero coefficient of r separately, in two + ## passes. + ## + ## Multiplying a chunk y_i by some t^j is the same as shifting it left by j + ## bits (or would be if GCM weren't backwards, but let's not worry about + ## that right now). The high j bits will spill over into the next chunk, + ## while the low n - j bits will stay where they are. It's these high bits + ## which cause trouble -- particularly the high bits of the top chunk, + ## since we'll add them on to y_m, which will need further reduction. But + ## only the topmost j bits will do this. + ## + ## The trick is that we do all of the bits which spill over first -- all of + ## the top j bits in each chunk, for each j -- in one pass, and then a + ## second pass of all the bits which don't. Because j, j' < n/2 for any + ## two nonzero coefficient degrees j and j', we have j + j' < n whence j < + ## n - j' -- so all of the bits contributed to y_m will be handled in the + ## second pass when we handle the bits that don't spill over. + rr = [i for i in xrange(1, w) if p.testbit(i)] + m = gfmask(redcwd) + + ## Handle the spilling bits. + yy = split_gf(y.storeb(w/4), redcwd) + b = C.GF(0) + for rj in rr: + br = [(yi << (redcwd - rj))&m for yi in yy[w/redcwd:]] + presfn(TAG_REDCBITS, w, join_gf(br, redcwd), w, dispwd, 'b(%d)' % rj) + b += join_gf(br, redcwd) << (w - redcwd) + presfn(TAG_REDCFULL, w, b, 2*w, dispwd, 'b') + s = y + b + presfn(TAG_REDCMIX, w, s, 2*w, dispwd, 's') + + ## Handle the nonspilling bits. + ss = split_gf(s.storeb(w/4), redcwd) + a = C.GF(0) + for rj in rr: + ar = [si >> rj for si in ss[w/redcwd:]] + presfn(TAG_REDCBITS, w, join_gf(ar, redcwd), w, dispwd, 'a(%d)' % rj) + a += join_gf(ar, redcwd) + presfn(TAG_REDCFULL, w, a, w, dispwd, 'a') + + ## Mix everything together. + m = gfmask(w) + z = (s&m) + (s >> w) + a + presfn(TAG_OUTPUT, w, z, w, dispwd, 'z') + + ## And we're done. + return z.storeb(w/8) + +@demo +def demo_pclmul(u, v): + return poly64_common(u, v, presfn = present_gf_pclmul) + +@demo +def demo_vmullp64(u, v): + w = 8*len(u) + return poly64_common(u, v, presfn = present_gf_mullp64, + redcwd = w%64 == 32 and 32 or 64) + +@demo +def demo_pmull(u, v): + w = 8*len(u) + return poly64_common(u, v, presfn = present_gf_pmull, + redcwd = w%64 == 32 and 32 or 64) + +###-------------------------------------------------------------------------- +### @@@ Random debris to be deleted. @@@ + +def cutting_room_floor(): + + x = C.bytes('cde4bef260d7bcda163547d348b7551195e77022907dd1df') + y = C.bytes('f7dac5c9941d26d0c6eb14ad568f86edd1dc9268eeee5332') + + u, v = C.GF.loadb(x), C.GF.loadb(y) + + g = u*v << 1 + print 'y = %s' % words(g.storeb(48)) + b1 = (g&repmask(0x01, 32, 6)) << 191 + b2 = (g&repmask(0x03, 32, 6)) << 190 + b7 = (g&repmask(0x7f, 32, 6)) << 185 + b = b1 + b2 + b7 + print 'b = %s' % words(b.storeb(48)[0:28]) + h = g + b + print 'w = %s' % words(h.storeb(48)) + + a0 = (h&repmask(0xffffffff, 32, 6)) << 192 + a1 = (h&repmask(0xfffffffe, 32, 6)) << 191 + a2 = (h&repmask(0xfffffffc, 32, 6)) << 190 + a7 = (h&repmask(0xffffff80, 32, 6)) << 185 + a = a0 + a1 + a2 + a7 + + print ' a_1 = %s' % words(a1.storeb(48)[0:24]) + print ' a_2 = %s' % words(a2.storeb(48)[0:24]) + print ' a_7 = %s' % words(a7.storeb(48)[0:24]) + + print 'low+unit = %s' % words((h + a0).storeb(48)[0:24]) + print ' low+0,2 = %s' % words((h + a0 + a2).storeb(48)[0:24]) + print ' 1,7 = %s' % words((a1 + a7).storeb(48)[0:24]) + + print 'a = %s' % words(a.storeb(48)[0:24]) + z = h + a + print 'z = %s' % words(z.storeb(48)) + + z = gcm_mul(x, y) + print 'u v mod p = %s' % words(z) + +###-------------------------------------------------------------------------- +### Main program. + +style = argv[1] +u = C.bytes(argv[2]) +v = C.bytes(argv[3]) +zz = DEMOMAP[style](u, v) +assert zz == gcm_mul(u, v) + +###----- That's all, folks --------------------------------------------------