Text file src/crypto/internal/fips140/aes/ctr_loong64.s

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build !purego
     6  
     7  // AES-CTR keystream generation for loong64 using LSX vector instructions.
     8  //
     9  // This file implements ctrBlocks1Asm/ctrBlocks2Asm/ctrBlocks4Asm/ctrBlocks8Asm,
    10  // which encrypt 1/2/4/8 counter blocks per call respectively and XOR the
    11  // resulting keystream into the source buffer.
    12  //
    13  // SUBBYTES and MIXCOLUMNS are macro-for-macro identical to the versions
    14  // defined in aes_loong64.s (same VSHUFB-based S-box split and same
    15  // XTIME-based column-mixing identity), but are redefined independently
    16  // in this file rather than shared via a common #include. This mirrors
    17  // the amd64/arm64 convention of aes_{amd64,arm64}.s and ctr_{amd64,arm64}.s
    18  // not sharing macros across files: each file is self-contained and can be
    19  // read/reviewed/regenerated without cross-file macro-expansion context.
    20  // The only symbol actually shared across the two files is the sbox0_0
    21  // S-box table and the shiftRows/byteSwap32/rot1/rot2/rot3 permutation
    22  // tables, which are defined once in aes_loong64.s as package-global
    23  // (non-<>) symbols and referenced here by plain name.
    24  
    25  #include "textflag.h"
    26  
    27  #define SUBBYTES(src, sbox_ptr, out) \
    28      VANDB   $0xe0, src, V25;     \  // V25 = src & 0xe0, keep only bit7/bit6/bit5
    29      VSRAB   $7,  V25,  V31;      \  // V31 = byte-wise broadcast of bit7 (0xFF/0x00)
    30      VSLLB   $1,  V25,  V24;      \  // shift bit6 into the sign position
    31      VSRAB   $7,  V24,  V30;      \  // V30 = byte-wise broadcast of bit6
    32      VSLLB   $2,  V25,  V24;      \  // shift bit5 into the sign position
    33      VSRAB   $7,  V24,  V29;      \  // V29 = byte-wise broadcast of bit5
    34      VANDB   $0x1f, src, V26;     \  // V26 = src & 0x1f, index for VSHUFB 32-way lookup
    35      \
    36      /* ---- 2. Chunk0/1 -> r01 (V16..V19,V28,V27 freed after use) ---- */ \
    37      VMOVQ   (sbox_ptr),   V16;   \
    38      VMOVQ   16(sbox_ptr), V17;   \
    39      VMOVQ   32(sbox_ptr), V18;   \
    40      VMOVQ   48(sbox_ptr), V19;   \
    41      VSHUFB  V26, V16, V17, V28;  \  // V28 = chunk0_raw
    42      VSHUFB  V26, V18, V19, V27;  \  // V27 = chunk1_raw
    43      VBITSELV V29, V27, V28, V20; \  // V20 = r01 = M5 ? chunk1 : chunk0
    44      \
    45      /* ---- 3. Chunk2/3 -> r23 ---- */ \
    46      VMOVQ   64(sbox_ptr),  V16;  \
    47      VMOVQ   80(sbox_ptr),  V17;  \
    48      VMOVQ   96(sbox_ptr),  V18;  \
    49      VMOVQ   112(sbox_ptr), V19;  \
    50      VSHUFB  V26, V16, V17, V28;  \  // V28 = chunk2_raw
    51      VSHUFB  V26, V18, V19, V27;  \  // V27 = chunk3_raw
    52      VBITSELV V29, V27, V28, V21; \  // V21 = r23
    53      \
    54      /* ---- 4. Merge first group (chunk0..3) -> r0123 ---- */ \
    55      VBITSELV V30, V21, V20, V22; \  // V22 = r0123 = M6 ? r23 : r01
    56      \
    57      /* ---- 5. Chunk4/5 -> r45 ---- */ \
    58      VMOVQ   128(sbox_ptr), V16;  \
    59      VMOVQ   144(sbox_ptr), V17;  \
    60      VMOVQ   160(sbox_ptr), V18;  \
    61      VMOVQ   176(sbox_ptr), V19;  \
    62      VSHUFB  V26, V16, V17, V28;  \  // V28 = chunk4_raw
    63      VSHUFB  V26, V18, V19, V27;  \  // V27 = chunk5_raw
    64      VBITSELV V29, V27, V28, V20; \  // V20 reused = r45
    65      \
    66      /* ---- 6. Chunk6/7 -> r67 ---- */ \
    67      VMOVQ   192(sbox_ptr), V16;  \
    68      VMOVQ   208(sbox_ptr), V17;  \
    69      VMOVQ   224(sbox_ptr), V18;  \
    70      VMOVQ   240(sbox_ptr), V19;  \
    71      VSHUFB  V26, V16, V17, V28;  \  // V28 = chunk6_raw
    72      VSHUFB  V26, V18, V19, V27;  \  // V27 = chunk7_raw
    73      VBITSELV V29, V27, V28, V21; \  // V21 reused = r67
    74      \
    75      /* ---- 7. Merge second group (chunk4..7) -> r4567 ---- */ \
    76      VBITSELV V30, V21, V20, V23; \  // V23 = r4567 = M6 ? r67 : r45
    77      \
    78      /* ---- 8. Final top-level merge ---- */ \
    79      VBITSELV V31, V23, V22, out      // out = M7 ? r4567 : r0123
    80  
    81  // -----------------------------------------------------------------------
    82  // MixColumns helper: multiply each byte of Vn by 2 in GF(2^8).
    83  //   xtime(a) = (a << 1) ^ (0x1b if a & 0x80 else 0)
    84  // -----------------------------------------------------------------------
    85  #define XTIME(src, dst, tmp) \
    86      VSLLB $1, src, dst; \     /* dst = src << 1 */
    87      VSRAB $7, src, tmp; \     /* tmp[i] = 0xff if src[i]>=0x80, else 0x00 */
    88      VANDB $0x1b, tmp, tmp; \  /* tmp[i] = 0x1b if src[i]>=0x80, else 0x00 */
    89      VXORV tmp, dst, dst       /* dst ^= tmp */
    90  
    91  #define MIXCOLUMNS(src, out, r1, r2, r3, t1, t2, t3) \
    92      VSHUFB r1, src, src, t1; \      /* t1 = rot1(a) */
    93      VXORV  src, t1, t2; \           /* t2 = a ^ rot1(a) */
    94      VSHUFB r2, src, src, t3; \      /* t3 = rot2(a) */
    95      VXORV  t2, t3, out; \           /* out = a^rot1(a)^rot2(a) */
    96      VSHUFB r3, src, src, t3; \      /* t3 = rot3(a) */
    97      VXORV  out, t3, out; \          /* out = t = a0^a1^a2^a3(each byte) */
    98      XTIME(t2, t1, t3); \            /* t1 = xtime(a^rot1(a)) */
    99      VXORV  src, out, out; \         /* out = a ^ t */
   100      VXORV  out, t1, out             /* out ^= xtime(...) */
   101  
   102  // func ctrBlocks1Asm(nr int, xk *[60]uint32, dst, src *[BlockSize]byte, ivlo, ivhi uint64)
   103  TEXT ·ctrBlocks1Asm(SB), NOSPLIT, $16-48
   104      MOVV nr+0(FP),    R4
   105      MOVV xk+8(FP),    R5
   106      MOVV dst+16(FP),  R6
   107      MOVV src+24(FP),  R7
   108      MOVV ivlo+32(FP), R8
   109      MOVV ivhi+40(FP), R9
   110  
   111      // Construct a 128-bit counter block onto the stack, big endian [ivhi][ivlo]
   112      REVBV R9, R10          // ivhi little -> big
   113      REVBV R8, R11          // ivlo little -> big
   114      MOVV  R10, 0(R3)
   115      MOVV  R11, 8(R3)
   116      VMOVQ (R3), V0         // V0 = counter block
   117  
   118      MOVV $shiftRows(SB), R12
   119      VMOVQ (R12), V7
   120      MOVV $byteSwap32(SB), R12
   121      VMOVQ (R12), V2
   122      MOVV $rot1(SB), R12
   123      VMOVQ (R12), V10
   124      MOVV $rot2(SB), R12
   125      VMOVQ (R12), V11
   126      MOVV $rot3(SB), R12
   127      VMOVQ (R12), V12
   128      MOVV $sbox0_0(SB), R14
   129  
   130      // AddRoundKey
   131      VMOVQ (R5), V8
   132      ADDV  $16, R5
   133      VSHUFB V2, V8, V8, V8 // V8 = byte-swap each 32-bit word of round key
   134      VXORV  V8, V0, V0
   135  
   136      // middle round: nr-1
   137      MOVV R4, R12
   138      ADDV $-1, R12
   139  Lenc_loop:
   140      SUBBYTES(V0, R14, V0)
   141  
   142      // ShiftRows
   143      VSHUFB V7, V0, V0, V0
   144  
   145      MIXCOLUMNS(V0, V1, V10, V11, V12, V3, V4, V5)
   146  
   147      // AddRoundKey
   148      VMOVQ (R5), V8
   149      ADDV  $16, R5
   150      VSHUFB V2, V8, V8, V8
   151      VXORV  V8, V1, V0
   152  
   153      ADDV $-1, R12
   154      BNE  R12, R0, Lenc_loop
   155  
   156      // last round: SubBytes + ShiftRows + AddRoundKey (no MixColumns)
   157      SUBBYTES(V0, R14, V0)
   158      VSHUFB V7, V0, V0, V0
   159      VMOVQ (R5), V8
   160      VSHUFB V2, V8, V8, V8
   161      VXORV V8, V0, V0
   162  
   163      VMOVQ (R7), V1
   164      VXORV V0, V1, V0
   165      VMOVQ V0, (R6)
   166  
   167      RET
   168  
   169  // func ctrBlocks2Asm(nr int, xk *[60]uint32, dst, src *[2*BlockSize]byte, ivlo, ivhi uint64)
   170  TEXT ·ctrBlocks2Asm(SB), NOSPLIT, $32-48
   171      MOVV nr+0(FP),    R4
   172      MOVV xk+8(FP),    R5
   173      MOVV dst+16(FP),  R6
   174      MOVV src+24(FP),  R7
   175      MOVV ivlo+32(FP), R8
   176      MOVV ivhi+40(FP), R9
   177  
   178      // Build counter 0 = (ivlo, ivhi)
   179      REVBV R9, R10
   180      REVBV R8, R11
   181      MOVV  R10, 0(R3)
   182      MOVV  R11, 8(R3)
   183      VMOVQ (R3), V0
   184  
   185      // Build counter 1 = (ivlo+1, ivhi + carry)
   186      MOVV  R8, R16
   187      ADDV  $1, R16, R17          // R17 = ivlo+1
   188      SGTU  R16, R17, R18         // R18 = 1 if overflow (unsigned wraparound), else 0
   189      ADDV  R9, R18, R19          // R19 = ivhi + carry
   190      REVBV R19, R10
   191      REVBV R17, R11
   192      MOVV  R10, 16(R3)
   193      MOVV  R11, 24(R3)
   194      VMOVQ 16(R3), V1
   195  
   196      // Load persistent constant tables (same as ctrBlocks1Asm)
   197      MOVV $shiftRows(SB), R12
   198      VMOVQ (R12), V7
   199      MOVV $byteSwap32(SB), R12
   200      VMOVQ (R12), V2
   201      MOVV $rot1(SB), R12
   202      VMOVQ (R12), V10
   203      MOVV $rot2(SB), R12
   204      VMOVQ (R12), V11
   205      MOVV $rot3(SB), R12
   206      VMOVQ (R12), V12
   207      MOVV $sbox0_0(SB), R14
   208  
   209      // Initial AddRoundKey (both blocks share the same first round key)
   210      VMOVQ (R5), V8
   211      ADDV  $16, R5
   212      VSHUFB V2, V8, V8, V8
   213      VXORV  V8, V0, V0
   214      VXORV  V8, V1, V1
   215  
   216      MOVV  R4, R12
   217      ADDV  $-1, R12          // R12 = nr-1 main rounds
   218  
   219  Lenc2_loop:
   220      // Round key for this round (shared)
   221      VMOVQ (R5), V8
   222      ADDV  $16, R5
   223      VSHUFB V2, V8, V8, V8
   224  
   225      // Block 0
   226      SUBBYTES(V0, R14, V13)
   227      VSHUFB V7, V13, V13, V0
   228      MIXCOLUMNS(V0, V3, V10, V11, V12, V4, V5, V6)
   229      VXORV  V8, V3, V0
   230  
   231      // Block 1
   232      SUBBYTES(V1, R14, V13)
   233      VSHUFB V7, V13, V13, V1
   234      MIXCOLUMNS(V1, V3, V10, V11, V12, V4, V5, V6)
   235      VXORV  V8, V3, V1
   236  
   237      ADDV $-1, R12
   238      BNE  R12, R0, Lenc2_loop
   239  
   240      // Final round: SubBytes + ShiftRows + AddRoundKey (no MixColumns)
   241      VMOVQ (R5), V8
   242      VSHUFB V2, V8, V8, V8
   243  
   244      SUBBYTES(V0, R14, V13)
   245      VSHUFB V7, V13, V13, V0
   246      VXORV  V8, V0, V0
   247  
   248      SUBBYTES(V1, R14, V13)
   249      VSHUFB V7, V13, V13, V1
   250      VXORV  V8, V1, V1
   251  
   252      // XOR plaintext, store
   253      VMOVQ (R7),    V20
   254      VMOVQ 16(R7),  V21
   255      VXORV V0, V20, V0
   256      VXORV V1, V21, V1
   257      VMOVQ V0, (R6)
   258      VMOVQ V1, 16(R6)
   259  
   260      RET
   261  
   262  // func ctrBlocks4Asm(nr int, xk *[60]uint32, dst, src *[4*BlockSize]byte, ivlo, ivhi uint64)
   263  TEXT ·ctrBlocks4Asm(SB), NOSPLIT, $16-48
   264      MOVV nr+0(FP),    R4
   265      MOVV xk+8(FP),    R5
   266      MOVV dst+16(FP),  R6
   267      MOVV src+24(FP),  R7
   268      MOVV ivlo+32(FP), R8
   269      MOVV ivhi+40(FP), R9
   270  
   271      // Construct 4 consecutive counter blocks in sequence (big endian), ivlo+1 needs to process carry between blocks
   272      REVBV R9, R10
   273      REVBV R8, R11
   274      MOVV  R10, 0(R3)
   275      MOVV  R11, 8(R3)
   276      VMOVQ (R3), V0            // block 0
   277  
   278      ADDV  $1, R8, R16         // R16 = ivlo+1
   279      SGTU  R16, R8, R17        // R17 = 1 if not overflow (R16 > R8); if overflow R17=0
   280      XOR   $1, R17             // R17 = 1 overflow need carry
   281      ADDV  R17, R9, R18        // R18 = ivhi + carry
   282      REVBV R18, R10
   283      REVBV R16, R11
   284      MOVV  R10, 0(R3)
   285      MOVV  R11, 8(R3)
   286      VMOVQ (R3), V1            // block 1
   287  
   288      ADDV  $1, R16, R23
   289      SGTU  R23, R16, R17
   290      XOR   $1, R17
   291      ADDV  R17, R18, R24
   292      REVBV R24, R10
   293      REVBV R23, R11
   294      MOVV  R10, 0(R3)
   295      MOVV  R11, 8(R3)
   296      VMOVQ (R3), V3            // block 2
   297  
   298      ADDV  $1, R23, R25
   299      SGTU  R25, R23, R17
   300      XOR   $1, R17
   301      ADDV  R17, R24, R26
   302      REVBV R26, R10
   303      REVBV R25, R11
   304      MOVV  R10, 0(R3)
   305      MOVV  R11, 8(R3)
   306      VMOVQ (R3), V4            // block 3
   307  
   308      MOVV $shiftRows(SB), R12
   309      VMOVQ (R12), V7
   310      MOVV $byteSwap32(SB), R12
   311      VMOVQ (R12), V2
   312      MOVV $rot1(SB), R12
   313      VMOVQ (R12), V10
   314      MOVV $rot2(SB), R12
   315      VMOVQ (R12), V11
   316      MOVV $rot3(SB), R12
   317      VMOVQ (R12), V12
   318      MOVV $sbox0_0(SB), R14
   319  
   320      // Initial AddRoundKey (4 blocks share the same round key)
   321      VMOVQ (R5), V8
   322      VSHUFB V2, V8, V8, V8
   323      VXORV  V8, V0, V0
   324      VXORV  V8, V1, V1
   325      VXORV  V8, V3, V3
   326      VXORV  V8, V4, V4
   327      ADDV  $16, R5
   328  
   329      MOVV  R4, R15
   330      ADDV  $-1, R15
   331  
   332  Lenc4_loop:
   333      SUBBYTES(V0, R14, V13)
   334      VSHUFB V7, V13, V13, V0
   335      MIXCOLUMNS(V0, V13, V10, V11, V12, V5, V6, V9)
   336  
   337      SUBBYTES(V1, R14, V14)
   338      VSHUFB V7, V14, V14, V1
   339      MIXCOLUMNS(V1, V14, V10, V11, V12, V5, V6, V9)
   340  
   341      SUBBYTES(V3, R14, V15)
   342      VSHUFB V7, V15, V15, V3
   343      MIXCOLUMNS(V3, V15, V10, V11, V12, V5, V6, V9)
   344  
   345      SUBBYTES(V4, R14, V16)
   346      VSHUFB V7, V16, V16, V4
   347      MIXCOLUMNS(V4, V16, V10, V11, V12, V5, V6, V9)
   348  
   349      VMOVQ (R5), V8
   350      VSHUFB V2, V8, V8, V8
   351      VXORV  V8, V13, V0
   352      VXORV  V8, V14, V1
   353      VXORV  V8, V15, V3
   354      VXORV  V8, V16, V4
   355      ADDV  $16, R5
   356  
   357      ADDV  $-1, R15
   358      BNE   R15, R0, Lenc4_loop
   359  
   360      // last round: SubBytes + ShiftRows + AddRoundKey (no MixColumns)
   361      VMOVQ (R5), V8
   362      VSHUFB V2, V8, V8, V8
   363  
   364      SUBBYTES(V0, R14, V13)
   365      VSHUFB V7, V13, V13, V0
   366      VXORV  V8, V0, V0
   367  
   368      SUBBYTES(V1, R14, V13)
   369      VSHUFB V7, V13, V13, V1
   370      VXORV  V8, V1, V1
   371  
   372      SUBBYTES(V3, R14, V13)
   373      VSHUFB V7, V13, V13, V3
   374      VXORV  V8, V3, V3
   375  
   376      SUBBYTES(V4, R14, V13)
   377      VSHUFB V7, V13, V13, V4
   378      VXORV  V8, V4, V4
   379  
   380      VMOVQ (R7),   V14
   381      VMOVQ 16(R7), V15
   382      VMOVQ 32(R7), V16
   383      VMOVQ 48(R7), V17
   384      VXORV V0, V14, V14
   385      VXORV V1, V15, V15
   386      VXORV V3, V16, V16
   387      VXORV V4, V17, V17
   388      VMOVQ V14, (R6)
   389      VMOVQ V15, 16(R6)
   390      VMOVQ V16, 32(R6)
   391      VMOVQ V17, 48(R6)
   392  
   393      RET
   394  
   395  // func ctrBlocks8Asm(nr int, xk *[60]uint32, dst, src *[8*BlockSize]byte, ivlo, ivhi uint64)
   396  TEXT ·ctrBlocks8Asm(SB), NOSPLIT, $32-48
   397      MOVV nr+0(FP),    R4
   398      MOVV xk+8(FP),    R5
   399      MOVV dst+16(FP),  R6
   400      MOVV src+24(FP),  R7
   401      MOVV ivlo+32(FP), R8
   402      MOVV ivhi+40(FP), R9
   403  
   404      REVBV R9, R10
   405      REVBV R8, R11
   406      MOVV  R10, 0(R3)
   407      MOVV  R11, 8(R3)
   408      VMOVQ (R3), V0
   409  
   410      ADDV  $1, R8, R16
   411      SGTU  R8, R16, R17
   412      ADDV  R17, R9, R17
   413      MOVV  R16, R8
   414      MOVV  R17, R9
   415      REVBV R9, R10
   416      REVBV R8, R11
   417      MOVV  R10, 16(R3)
   418      MOVV  R11, 24(R3)
   419      VMOVQ 16(R3), V1
   420  
   421      ADDV  $1, R8, R16
   422      SGTU  R8, R16, R17
   423      ADDV  R17, R9, R17
   424      MOVV  R16, R8
   425      MOVV  R17, R9
   426      REVBV R9, R10
   427      REVBV R8, R11
   428      MOVV  R10, 0(R3)
   429      MOVV  R11, 8(R3)
   430      VMOVQ (R3), V3
   431  
   432      ADDV  $1, R8, R16
   433      SGTU  R8, R16, R17
   434      ADDV  R17, R9, R17
   435      MOVV  R16, R8
   436      MOVV  R17, R9
   437      REVBV R9, R10
   438      REVBV R8, R11
   439      MOVV  R10, 16(R3)
   440      MOVV  R11, 24(R3)
   441      VMOVQ 16(R3), V4
   442  
   443      ADDV  $1, R8, R16
   444      SGTU  R8, R16, R17
   445      ADDV  R17, R9, R17
   446      MOVV  R16, R8
   447      MOVV  R17, R9
   448      REVBV R9, R10
   449      REVBV R8, R11
   450      MOVV  R10, 0(R3)
   451      MOVV  R11, 8(R3)
   452      VMOVQ (R3), V5
   453  
   454      ADDV  $1, R8, R16
   455      SGTU  R8, R16, R17
   456      ADDV  R17, R9, R17
   457      MOVV  R16, R8
   458      MOVV  R17, R9
   459      REVBV R9, R10
   460      REVBV R8, R11
   461      MOVV  R10, 16(R3)
   462      MOVV  R11, 24(R3)
   463      VMOVQ 16(R3), V6
   464  
   465      ADDV  $1, R8, R16
   466      SGTU  R8, R16, R17
   467      ADDV  R17, R9, R17
   468      MOVV  R16, R8
   469      MOVV  R17, R9
   470      REVBV R9, R10
   471      REVBV R8, R11
   472      MOVV  R10, 0(R3)
   473      MOVV  R11, 8(R3)
   474      VMOVQ (R3), V8
   475  
   476      ADDV  $1, R8, R16
   477      SGTU  R8, R16, R17
   478      ADDV  R17, R9, R17
   479      MOVV  R16, R8
   480      MOVV  R17, R9
   481      REVBV R9, R10
   482      REVBV R8, R11
   483      MOVV  R10, 16(R3)
   484      MOVV  R11, 24(R3)
   485      VMOVQ 16(R3), V9
   486  
   487      MOVV $shiftRows(SB), R12
   488      VMOVQ (R12), V7
   489      MOVV $byteSwap32(SB), R12
   490      VMOVQ (R12), V2
   491      MOVV $rot1(SB), R12
   492      VMOVQ (R12), V10
   493      MOVV $rot2(SB), R12
   494      VMOVQ (R12), V11
   495      MOVV $rot3(SB), R12
   496      VMOVQ (R12), V12
   497      MOVV $sbox0_0(SB), R14
   498  
   499      VMOVQ (R5), V15
   500      ADDV  $16, R5
   501      VSHUFB V2, V15, V15, V15
   502      VXORV  V15, V0, V0
   503      VXORV  V15, V1, V1
   504      VXORV  V15, V3, V3
   505      VXORV  V15, V4, V4
   506      VXORV  V15, V5, V5
   507      VXORV  V15, V6, V6
   508      VXORV  V15, V8, V8
   509      VXORV  V15, V9, V9
   510  
   511      MOVV R4, R13
   512      ADDV $-1, R13
   513  
   514  Lenc8_loop:
   515      // SubBytes + ShiftRows + MixColumns + AddRoundKey, Process 8 state blocks in sequence
   516      SUBBYTES(V0, R14, V0)
   517      SUBBYTES(V1, R14, V1)
   518      SUBBYTES(V3, R14, V3)
   519      SUBBYTES(V4, R14, V4)
   520      SUBBYTES(V5, R14, V5)
   521      SUBBYTES(V6, R14, V6)
   522      SUBBYTES(V8, R14, V8)
   523      SUBBYTES(V9, R14, V9)
   524  
   525      VSHUFB V7, V0, V0, V0
   526      VSHUFB V7, V1, V1, V1
   527      VSHUFB V7, V3, V3, V3
   528      VSHUFB V7, V4, V4, V4
   529      VSHUFB V7, V5, V5, V5
   530      VSHUFB V7, V6, V6, V6
   531      VSHUFB V7, V8, V8, V8
   532      VSHUFB V7, V9, V9, V9
   533  
   534      MIXCOLUMNS(V0, V23, V10, V11, V12, V20, V21, V22)
   535      MIXCOLUMNS(V1, V24, V10, V11, V12, V20, V21, V22)
   536      MIXCOLUMNS(V3, V25, V10, V11, V12, V20, V21, V22)
   537      MIXCOLUMNS(V4, V26, V10, V11, V12, V20, V21, V22)
   538      MIXCOLUMNS(V5, V27, V10, V11, V12, V20, V21, V22)
   539      MIXCOLUMNS(V6, V28, V10, V11, V12, V20, V21, V22)
   540      MIXCOLUMNS(V8, V29, V10, V11, V12, V20, V21, V22)
   541      MIXCOLUMNS(V9, V30, V10, V11, V12, V20, V21, V22)
   542  
   543      VMOVQ (R5), V15
   544      ADDV  $16, R5
   545      VSHUFB V2, V15, V15, V15
   546      VXORV  V15, V23, V0
   547      VXORV  V15, V24, V1
   548      VXORV  V15, V25, V3
   549      VXORV  V15, V26, V4
   550      VXORV  V15, V27, V5
   551      VXORV  V15, V28, V6
   552      VXORV  V15, V29, V8
   553      VXORV  V15, V30, V9
   554  
   555      ADDV $-1, R13
   556      BNE  R13, R0, Lenc8_loop
   557  
   558      // last round: SubBytes + ShiftRows + AddRoundKey (no MixColumns)
   559      SUBBYTES(V0, R14, V0)
   560      SUBBYTES(V1, R14, V1)
   561      SUBBYTES(V3, R14, V3)
   562      SUBBYTES(V4, R14, V4)
   563      SUBBYTES(V5, R14, V5)
   564      SUBBYTES(V6, R14, V6)
   565      SUBBYTES(V8, R14, V8)
   566      SUBBYTES(V9, R14, V9)
   567  
   568      VSHUFB V7, V0, V0, V0
   569      VSHUFB V7, V1, V1, V1
   570      VSHUFB V7, V3, V3, V3
   571      VSHUFB V7, V4, V4, V4
   572      VSHUFB V7, V5, V5, V5
   573      VSHUFB V7, V6, V6, V6
   574      VSHUFB V7, V8, V8, V8
   575      VSHUFB V7, V9, V9, V9
   576  
   577      VMOVQ (R5), V15
   578      VSHUFB V2, V15, V15, V15
   579      VXORV  V15, V0, V0
   580      VXORV  V15, V1, V1
   581      VXORV  V15, V3, V3
   582      VXORV  V15, V4, V4
   583      VXORV  V15, V5, V5
   584      VXORV  V15, V6, V6
   585      VXORV  V15, V8, V8
   586      VXORV  V15, V9, V9
   587  
   588      VMOVQ (0*16)(R7), V16;  VXORV V0, V16, V16;  VMOVQ V16, (0*16)(R6)
   589      VMOVQ (1*16)(R7), V17;  VXORV V1, V17, V17;  VMOVQ V17, (1*16)(R6)
   590      VMOVQ (2*16)(R7), V18;  VXORV V3, V18, V18;  VMOVQ V18, (2*16)(R6)
   591      VMOVQ (3*16)(R7), V19;  VXORV V4, V19, V19;  VMOVQ V19, (3*16)(R6)
   592      VMOVQ (4*16)(R7), V20;  VXORV V5, V20, V20;  VMOVQ V20, (4*16)(R6)
   593      VMOVQ (5*16)(R7), V21;  VXORV V6, V21, V21;  VMOVQ V21, (5*16)(R6)
   594      VMOVQ (6*16)(R7), V22;  VXORV V8, V22, V22;  VMOVQ V22, (6*16)(R6)
   595      VMOVQ (7*16)(R7), V23;  VXORV V9, V23, V23;  VMOVQ V23, (7*16)(R6)
   596  
   597      RET
   598  

View as plain text