Text file src/crypto/internal/fips140/sha3/sha3_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  // SHA-3 (Keccak-f[1600]) for LoongArch LSX, two lanes per register.
     8  // Column x is stored as:
     9  //   V(0+x)  = [L(x,0), L(x,1)]
    10  //   V(5+x)  = [L(x,2), L(x,3)]
    11  //   V(10+x) = [L(x,4), x]      (element 1 undefined; masked by V31 in theta)
    12  // V15-V19 parity/pi-A, V20-V24 D/pi-B, V25-V29 pi-C, V30 tmp, V31 mask.
    13  
    14  #include "textflag.h"
    15  
    16  TEXT ·keccakF1600LSX(SB), NOSPLIT, $200-8
    17  	MOVV	a+0(FP), R4
    18  	MOVV	$round_consts<>(SB), R6
    19  	MOVV	$rho_pairs<>(SB), R8
    20  	MOVV	$24, R7
    21  
    22  	// V31 = [-1, 0] mask (element 0 set, element 1 clear).
    23  	VXORV	V31, V31, V31
    24  	MOVV	$-1, R5
    25  	VMOVQ	R5, V31.V[0]
    26  
    27  	// Load state: A_x = lanes (x, x+5), B_x = (x+10, x+15), C_x = (x+20, 0).
    28  	MOVV	0(R4), R5
    29  	VMOVQ	R5, V0.V[0]
    30  	MOVV	40(R4), R5
    31  	VMOVQ	R5, V0.V[1]
    32  	MOVV	8(R4), R5
    33  	VMOVQ	R5, V1.V[0]
    34  	MOVV	48(R4), R5
    35  	VMOVQ	R5, V1.V[1]
    36  	MOVV	16(R4), R5
    37  	VMOVQ	R5, V2.V[0]
    38  	MOVV	56(R4), R5
    39  	VMOVQ	R5, V2.V[1]
    40  	MOVV	24(R4), R5
    41  	VMOVQ	R5, V3.V[0]
    42  	MOVV	64(R4), R5
    43  	VMOVQ	R5, V3.V[1]
    44  	MOVV	32(R4), R5
    45  	VMOVQ	R5, V4.V[0]
    46  	MOVV	72(R4), R5
    47  	VMOVQ	R5, V4.V[1]
    48  
    49  	MOVV	80(R4), R5
    50  	VMOVQ	R5, V5.V[0]
    51  	MOVV	120(R4), R5
    52  	VMOVQ	R5, V5.V[1]
    53  	MOVV	88(R4), R5
    54  	VMOVQ	R5, V6.V[0]
    55  	MOVV	128(R4), R5
    56  	VMOVQ	R5, V6.V[1]
    57  	MOVV	96(R4), R5
    58  	VMOVQ	R5, V7.V[0]
    59  	MOVV	136(R4), R5
    60  	VMOVQ	R5, V7.V[1]
    61  	MOVV	104(R4), R5
    62  	VMOVQ	R5, V8.V[0]
    63  	MOVV	144(R4), R5
    64  	VMOVQ	R5, V8.V[1]
    65  	MOVV	112(R4), R5
    66  	VMOVQ	R5, V9.V[0]
    67  	MOVV	152(R4), R5
    68  	VMOVQ	R5, V9.V[1]
    69  
    70  	VXORV	V10, V10, V10
    71  	VXORV	V11, V11, V11
    72  	VXORV	V12, V12, V12
    73  	VXORV	V13, V13, V13
    74  	VXORV	V14, V14, V14
    75  	MOVV	160(R4), R5
    76  	VMOVQ	R5, V10.V[0]
    77  	MOVV	168(R4), R5
    78  	VMOVQ	R5, V11.V[0]
    79  	MOVV	176(R4), R5
    80  	VMOVQ	R5, V12.V[0]
    81  	MOVV	184(R4), R5
    82  	VMOVQ	R5, V13.V[0]
    83  	MOVV	192(R4), R5
    84  	VMOVQ	R5, V14.V[0]
    85  
    86  loop:
    87  	// Theta: C[x] = parity of column x -> V15+x, both elements.
    88  	// T = A^B^(C&mask); PC = T ^ swap(T).
    89  	VXORV	V0, V5, V30
    90  	VANDV	V31, V10, V29
    91  	VXORV	V30, V29, V30
    92  	VILVHV	V30, V30, V29
    93  	VILVLV	V29, V30, V29
    94  	VXORV	V30, V29, V15	// C[0]
    95  
    96  	VXORV	V1, V6, V30
    97  	VANDV	V31, V11, V29
    98  	VXORV	V30, V29, V30
    99  	VILVHV	V30, V30, V29
   100  	VILVLV	V29, V30, V29
   101  	VXORV	V30, V29, V16	// C[1]
   102  
   103  	VXORV	V2, V7, V30
   104  	VANDV	V31, V12, V29
   105  	VXORV	V30, V29, V30
   106  	VILVHV	V30, V30, V29
   107  	VILVLV	V29, V30, V29
   108  	VXORV	V30, V29, V17	// C[2]
   109  
   110  	VXORV	V3, V8, V30
   111  	VANDV	V31, V13, V29
   112  	VXORV	V30, V29, V30
   113  	VILVHV	V30, V30, V29
   114  	VILVLV	V29, V30, V29
   115  	VXORV	V30, V29, V18	// C[3]
   116  
   117  	VXORV	V4, V9, V30
   118  	VANDV	V31, V14, V29
   119  	VXORV	V30, V29, V30
   120  	VILVHV	V30, V30, V29
   121  	VILVLV	V29, V30, V29
   122  	VXORV	V30, V29, V19	// C[4]
   123  
   124  	// D_x = C[x-1] ^ rotl(C[x+1],1) -> V20+x (broadcast both elements).
   125  	VROTRV	$63, V16, V30
   126  	VXORV	V19, V30, V20	// D0
   127  	VROTRV	$63, V17, V30
   128  	VXORV	V15, V30, V21	// D1
   129  	VROTRV	$63, V18, V30
   130  	VXORV	V16, V30, V22	// D2
   131  	VROTRV	$63, V19, V30
   132  	VXORV	V17, V30, V23	// D3
   133  	VROTRV	$63, V15, V30
   134  	VXORV	V18, V30, V24	// D4
   135  
   136  	// Theta apply + rho: per reg, R = rotr(R ^ D_x, rho-pair).
   137  	VXORV	V20, V0, V0
   138  	VMOVQ	0(R8), V30
   139  	VROTRV	V30, V0, V0
   140  	VXORV	V21, V1, V1
   141  	VMOVQ	16(R8), V30
   142  	VROTRV	V30, V1, V1
   143  	VXORV	V22, V2, V2
   144  	VMOVQ	32(R8), V30
   145  	VROTRV	V30, V2, V2
   146  	VXORV	V23, V3, V3
   147  	VMOVQ	48(R8), V30
   148  	VROTRV	V30, V3, V3
   149  	VXORV	V24, V4, V4
   150  	VMOVQ	64(R8), V30
   151  	VROTRV	V30, V4, V4
   152  
   153  	VXORV	V20, V5, V5
   154  	VMOVQ	80(R8), V30
   155  	VROTRV	V30, V5, V5
   156  	VXORV	V21, V6, V6
   157  	VMOVQ	96(R8), V30
   158  	VROTRV	V30, V6, V6
   159  	VXORV	V22, V7, V7
   160  	VMOVQ	112(R8), V30
   161  	VROTRV	V30, V7, V7
   162  	VXORV	V23, V8, V8
   163  	VMOVQ	128(R8), V30
   164  	VROTRV	V30, V8, V8
   165  	VXORV	V24, V9, V9
   166  	VMOVQ	144(R8), V30
   167  	VROTRV	V30, V9, V9
   168  
   169  	VXORV	V20, V10, V10
   170  	VMOVQ	160(R8), V30
   171  	VROTRV	V30, V10, V10
   172  	VXORV	V21, V11, V11
   173  	VMOVQ	176(R8), V30
   174  	VROTRV	V30, V11, V11
   175  	VXORV	V22, V12, V12
   176  	VMOVQ	192(R8), V30
   177  	VROTRV	V30, V12, V12
   178  	VXORV	V23, V13, V13
   179  	VMOVQ	208(R8), V30
   180  	VROTRV	V30, V13, V13
   181  	VXORV	V24, V14, V14
   182  	VMOVQ	224(R8), V30
   183  	VROTRV	V30, V14, V14
   184  
   185  	// Pi: gather post-rho lanes into V15-V29.
   186  	// A'_x' = [L'(x',x'), L'((x'+3)%5, x')]
   187  	VILVLV	V0, V3, V15	// [L'(0,0), L'(3,0)]
   188  	VILVHV	V1, V4, V16	// [L'(1,1), L'(4,1)]
   189  	VILVLV	V7, V5, V17	// [L'(2,2), L'(0,2)]
   190  	VILVHV	V8, V6, V18	// [L'(3,3), L'(1,3)]
   191  	VILVLV	V14, V12, V19	// [L'(4,4), L'(2,4)]
   192  
   193  	// B'_x' = [L'((x'+1)%5, x'), L'((x'+4)%5, x')]
   194  	VILVLV	V1, V4, V20	// [L'(1,0), L'(4,0)]
   195  	VILVHV	V2, V0, V21	// [L'(2,1), L'(0,1)]
   196  	VILVLV	V8, V6, V22	// [L'(3,2), L'(1,2)]
   197  	VILVHV	V9, V7, V23	// [L'(4,3), L'(2,3)]
   198  	VILVLV	V10, V13, V24	// [L'(0,4), L'(3,4)]
   199  
   200  	// C'_x' = [L'((x'+2)%5, x'), 0]  (V31.e1 = 0 supplies the zero)
   201  	VILVLV	V2, V31, V25	// [L'(2,0), 0]
   202  	VILVHV	V3, V31, V26	// [L'(3,1), 0]
   203  	VILVLV	V9, V31, V27	// [L'(4,2), 0]
   204  	VILVHV	V5, V31, V28	// [L'(0,3), 0]
   205  	VILVLV	V11, V31, V29	// [L'(1,4), 0]
   206  
   207  	// Chi: out_x = in_x ^ (~in_{x+1} & in_{x+2}), per group, mod 5.
   208  	// Group A: sources V15-V19 -> dests V0-V4.
   209  	VANDNV	V17, V16, V30
   210  	VXORV	V15, V30, V0
   211  	VANDNV	V18, V17, V30
   212  	VXORV	V16, V30, V1
   213  	VANDNV	V19, V18, V30
   214  	VXORV	V17, V30, V2
   215  	VANDNV	V15, V19, V30
   216  	VXORV	V18, V30, V3
   217  	VANDNV	V16, V15, V30
   218  	VXORV	V19, V30, V4
   219  
   220  	// Group B: sources V20-V24 -> dests V5-V9.
   221  	VANDNV	V22, V21, V30
   222  	VXORV	V20, V30, V5
   223  	VANDNV	V23, V22, V30
   224  	VXORV	V21, V30, V6
   225  	VANDNV	V24, V23, V30
   226  	VXORV	V22, V30, V7
   227  	VANDNV	V20, V24, V30
   228  	VXORV	V23, V30, V8
   229  	VANDNV	V21, V20, V30
   230  	VXORV	V24, V30, V9
   231  
   232  	// Group C: sources V25-V29 -> dests V10-V14.
   233  	VANDNV	V27, V26, V30
   234  	VXORV	V25, V30, V10
   235  	VANDNV	V28, V27, V30
   236  	VXORV	V26, V30, V11
   237  	VANDNV	V29, V28, V30
   238  	VXORV	V27, V30, V12
   239  	VANDNV	V25, V29, V30
   240  	VXORV	V28, V30, V13
   241  	VANDNV	V26, V25, V30
   242  	VXORV	V29, V30, V14
   243  
   244  	// Iota: lane(0,0) = V0.e0 ^= RC[round] (mask to element 0).
   245  	MOVV	(R6), R5
   246  	VXORV	V30, V30, V30
   247  	VMOVQ	R5, V30.V[0]
   248  	VXORV	V30, V0, V0
   249  
   250  	ADDV	$8, R6
   251  	SUBV	$1, R7
   252  	BNE	R7, R0, loop
   253  
   254  	// Store lanes back.
   255  	VMOVQ	V0.V[0], 0(R4)
   256  	VMOVQ	V0.V[1], 40(R4)
   257  	VMOVQ	V1.V[0], 8(R4)
   258  	VMOVQ	V1.V[1], 48(R4)
   259  	VMOVQ	V2.V[0], 16(R4)
   260  	VMOVQ	V2.V[1], 56(R4)
   261  	VMOVQ	V3.V[0], 24(R4)
   262  	VMOVQ	V3.V[1], 64(R4)
   263  	VMOVQ	V4.V[0], 32(R4)
   264  	VMOVQ	V4.V[1], 72(R4)
   265  	VMOVQ	V5.V[0], 80(R4)
   266  	VMOVQ	V5.V[1], 120(R4)
   267  	VMOVQ	V6.V[0], 88(R4)
   268  	VMOVQ	V6.V[1], 128(R4)
   269  	VMOVQ	V7.V[0], 96(R4)
   270  	VMOVQ	V7.V[1], 136(R4)
   271  	VMOVQ	V8.V[0], 104(R4)
   272  	VMOVQ	V8.V[1], 144(R4)
   273  	VMOVQ	V9.V[0], 112(R4)
   274  	VMOVQ	V9.V[1], 152(R4)
   275  	VMOVQ	V10.V[0], 160(R4)
   276  	VMOVQ	V11.V[0], 168(R4)
   277  	VMOVQ	V12.V[0], 176(R4)
   278  	VMOVQ	V13.V[0], 184(R4)
   279  	VMOVQ	V14.V[0], 192(R4)
   280  	RET
   281  
   282  // rho_pairs: per-register right-rotation amounts = 64 - rho[lane].
   283  // Order: A_0..A_4, B_0..B_4, C_0..C_4.
   284  DATA	rho_pairs<>+0x00(SB)/8, $0x0000000000000000	// r(0,0)=0
   285  DATA	rho_pairs<>+0x08(SB)/8, $0x000000000000001c	// r(0,1)=36 -> 28
   286  DATA	rho_pairs<>+0x10(SB)/8, $0x000000000000003f	// r(1,0)=1 -> 63
   287  DATA	rho_pairs<>+0x18(SB)/8, $0x0000000000000014	// r(1,1)=44 -> 20
   288  DATA	rho_pairs<>+0x20(SB)/8, $0x0000000000000002	// r(2,0)=62 -> 2
   289  DATA	rho_pairs<>+0x28(SB)/8, $0x000000000000003a	// r(2,1)=6 -> 58
   290  DATA	rho_pairs<>+0x30(SB)/8, $0x0000000000000024	// r(3,0)=28 -> 36
   291  DATA	rho_pairs<>+0x38(SB)/8, $0x0000000000000009	// r(3,1)=55 -> 9
   292  DATA	rho_pairs<>+0x40(SB)/8, $0x0000000000000025	// r(4,0)=27 -> 37
   293  DATA	rho_pairs<>+0x48(SB)/8, $0x000000000000002c	// r(4,1)=20 -> 44
   294  
   295  DATA	rho_pairs<>+0x50(SB)/8, $0x000000000000003d	// r(0,2)=3 -> 61
   296  DATA	rho_pairs<>+0x58(SB)/8, $0x0000000000000017	// r(0,3)=41 -> 23
   297  DATA	rho_pairs<>+0x60(SB)/8, $0x0000000000000036	// r(1,2)=10 -> 54
   298  DATA	rho_pairs<>+0x68(SB)/8, $0x0000000000000013	// r(1,3)=45 -> 19
   299  DATA	rho_pairs<>+0x70(SB)/8, $0x0000000000000015	// r(2,2)=43 -> 21
   300  DATA	rho_pairs<>+0x78(SB)/8, $0x0000000000000031	// r(2,3)=15 -> 49
   301  DATA	rho_pairs<>+0x80(SB)/8, $0x0000000000000027	// r(3,2)=25 -> 39
   302  DATA	rho_pairs<>+0x88(SB)/8, $0x000000000000002b	// r(3,3)=21 -> 43
   303  DATA	rho_pairs<>+0x90(SB)/8, $0x0000000000000019	// r(4,2)=39 -> 25
   304  DATA	rho_pairs<>+0x98(SB)/8, $0x0000000000000038	// r(4,3)=8 -> 56
   305  
   306  DATA	rho_pairs<>+0xa0(SB)/8, $0x000000000000002e	// r(0,4)=18 -> 46
   307  DATA	rho_pairs<>+0xa8(SB)/8, $0
   308  DATA	rho_pairs<>+0xb0(SB)/8, $0x000000000000003e	// r(1,4)=2 -> 62
   309  DATA	rho_pairs<>+0xb8(SB)/8, $0
   310  DATA	rho_pairs<>+0xc0(SB)/8, $0x0000000000000003	// r(2,4)=61 -> 3
   311  DATA	rho_pairs<>+0xc8(SB)/8, $0
   312  DATA	rho_pairs<>+0xd0(SB)/8, $0x0000000000000008	// r(3,4)=56 -> 8
   313  DATA	rho_pairs<>+0xd8(SB)/8, $0
   314  DATA	rho_pairs<>+0xe0(SB)/8, $0x0000000000000032	// r(4,4)=14 -> 50
   315  DATA	rho_pairs<>+0xe8(SB)/8, $0
   316  GLOBL	rho_pairs<>(SB), NOPTR|RODATA, $240
   317  
   318  // Round constants
   319  DATA	round_consts<>+0x00(SB)/8, $0x0000000000000001
   320  DATA	round_consts<>+0x08(SB)/8, $0x0000000000008082
   321  DATA	round_consts<>+0x10(SB)/8, $0x800000000000808a
   322  DATA	round_consts<>+0x18(SB)/8, $0x8000000080008000
   323  DATA	round_consts<>+0x20(SB)/8, $0x000000000000808b
   324  DATA	round_consts<>+0x28(SB)/8, $0x0000000080000001
   325  DATA	round_consts<>+0x30(SB)/8, $0x8000000080008081
   326  DATA	round_consts<>+0x38(SB)/8, $0x8000000000008009
   327  DATA	round_consts<>+0x40(SB)/8, $0x000000000000008a
   328  DATA	round_consts<>+0x48(SB)/8, $0x0000000000000088
   329  DATA	round_consts<>+0x50(SB)/8, $0x0000000080008009
   330  DATA	round_consts<>+0x58(SB)/8, $0x000000008000000a
   331  DATA	round_consts<>+0x60(SB)/8, $0x000000008000808b
   332  DATA	round_consts<>+0x68(SB)/8, $0x800000000000008b
   333  DATA	round_consts<>+0x70(SB)/8, $0x8000000000008089
   334  DATA	round_consts<>+0x78(SB)/8, $0x8000000000008003
   335  DATA	round_consts<>+0x80(SB)/8, $0x8000000000008002
   336  DATA	round_consts<>+0x88(SB)/8, $0x8000000000000080
   337  DATA	round_consts<>+0x90(SB)/8, $0x000000000000800a
   338  DATA	round_consts<>+0x98(SB)/8, $0x800000008000000a
   339  DATA	round_consts<>+0xA0(SB)/8, $0x8000000080008081
   340  DATA	round_consts<>+0xA8(SB)/8, $0x8000000000008080
   341  DATA	round_consts<>+0xB0(SB)/8, $0x0000000080000001
   342  DATA	round_consts<>+0xB8(SB)/8, $0x8000000080008008
   343  GLOBL	round_consts<>(SB), NOPTR|RODATA, $192
   344  

View as plain text