Source file src/crypto/internal/fips140/sha3/_asm/keccakf_amd64_asm.go

     1  // Copyright 2024 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  // This code was translated into a form compatible with 6a from the public
     6  // domain sources at https://github.com/gvanas/KeccakCodePackage
     7  
     8  package main
     9  
    10  import (
    11  	"os"
    12  
    13  	. "github.com/mmcloughlin/avo/build"
    14  	. "github.com/mmcloughlin/avo/operand"
    15  	. "github.com/mmcloughlin/avo/reg"
    16  )
    17  
    18  //go:generate go run . -out ../sha3_amd64.s
    19  
    20  // Round Constants for use in the ι step.
    21  var RoundConstants = [24]uint64{
    22  	0x0000000000000001,
    23  	0x0000000000008082,
    24  	0x800000000000808A,
    25  	0x8000000080008000,
    26  	0x000000000000808B,
    27  	0x0000000080000001,
    28  	0x8000000080008081,
    29  	0x8000000000008009,
    30  	0x000000000000008A,
    31  	0x0000000000000088,
    32  	0x0000000080008009,
    33  	0x000000008000000A,
    34  	0x000000008000808B,
    35  	0x800000000000008B,
    36  	0x8000000000008089,
    37  	0x8000000000008003,
    38  	0x8000000000008002,
    39  	0x8000000000000080,
    40  	0x000000000000800A,
    41  	0x800000008000000A,
    42  	0x8000000080008081,
    43  	0x8000000000008080,
    44  	0x0000000080000001,
    45  	0x8000000080008008,
    46  }
    47  
    48  var (
    49  	// Temporary registers
    50  	rT1 GPPhysical = RAX
    51  
    52  	// Round vars
    53  	rpState = Mem{Base: RDI}
    54  	rpStack = Mem{Base: RSP}
    55  
    56  	rDa = RBX
    57  	rDe = RCX
    58  	rDi = RDX
    59  	rDo = R8
    60  	rDu = R9
    61  
    62  	rBa = R10
    63  	rBe = R11
    64  	rBi = R12
    65  	rBo = R13
    66  	rBu = R14
    67  
    68  	rCa = RSI
    69  	rCe = RBP
    70  	rCi = rBi
    71  	rCo = rBo
    72  	rCu = R15
    73  )
    74  
    75  const (
    76  	_ba = iota * 8
    77  	_be
    78  	_bi
    79  	_bo
    80  	_bu
    81  	_ga
    82  	_ge
    83  	_gi
    84  	_go
    85  	_gu
    86  	_ka
    87  	_ke
    88  	_ki
    89  	_ko
    90  	_ku
    91  	_ma
    92  	_me
    93  	_mi
    94  	_mo
    95  	_mu
    96  	_sa
    97  	_se
    98  	_si
    99  	_so
   100  	_su
   101  )
   102  
   103  func main() {
   104  	// https://github.com/mmcloughlin/avo/issues/450
   105  	os.Setenv("GOOS", "linux")
   106  	os.Setenv("GOARCH", "amd64")
   107  
   108  	Package("crypto/internal/fips140/sha3")
   109  	ConstraintExpr("!purego")
   110  	keccakF1600()
   111  	Generate()
   112  }
   113  
   114  func MOVQ_RBI_RCE() { MOVQ(rBi, rCe) }
   115  func XORQ_RT1_RCA() { XORQ(rT1, rCa) }
   116  func XORQ_RT1_RCE() { XORQ(rT1, rCe) }
   117  func XORQ_RBA_RCU() { XORQ(rBa, rCu) }
   118  func XORQ_RBE_RCU() { XORQ(rBe, rCu) }
   119  func XORQ_RDU_RCU() { XORQ(rDu, rCu) }
   120  func XORQ_RDA_RCA() { XORQ(rDa, rCa) }
   121  func XORQ_RDE_RCE() { XORQ(rDe, rCe) }
   122  
   123  type ArgMacro func()
   124  
   125  func mKeccakRound(
   126  	iState, oState Mem,
   127  	rc U64,
   128  	B_RBI_RCE, G_RT1_RCA, G_RT1_RCE, G_RBA_RCU,
   129  	K_RT1_RCA, K_RT1_RCE, K_RBA_RCU, M_RT1_RCA,
   130  	M_RT1_RCE, M_RBE_RCU, S_RDU_RCU, S_RDA_RCA,
   131  	S_RDE_RCE ArgMacro,
   132  ) {
   133  	Comment("Prepare round")
   134  	MOVQ(rCe, rDa)
   135  	ROLQ(Imm(1), rDa)
   136  
   137  	MOVQ(iState.Offset(_bi), rCi)
   138  	XORQ(iState.Offset(_gi), rDi)
   139  	XORQ(rCu, rDa)
   140  	XORQ(iState.Offset(_ki), rCi)
   141  	XORQ(iState.Offset(_mi), rDi)
   142  	XORQ(rDi, rCi)
   143  
   144  	MOVQ(rCi, rDe)
   145  	ROLQ(Imm(1), rDe)
   146  
   147  	MOVQ(iState.Offset(_bo), rCo)
   148  	XORQ(iState.Offset(_go), rDo)
   149  	XORQ(rCa, rDe)
   150  	XORQ(iState.Offset(_ko), rCo)
   151  	XORQ(iState.Offset(_mo), rDo)
   152  	XORQ(rDo, rCo)
   153  
   154  	MOVQ(rCo, rDi)
   155  	ROLQ(Imm(1), rDi)
   156  
   157  	MOVQ(rCu, rDo)
   158  	XORQ(rCe, rDi)
   159  	ROLQ(Imm(1), rDo)
   160  
   161  	MOVQ(rCa, rDu)
   162  	XORQ(rCi, rDo)
   163  	ROLQ(Imm(1), rDu)
   164  
   165  	Comment("Result b")
   166  	MOVQ(iState.Offset(_ba), rBa)
   167  	MOVQ(iState.Offset(_ge), rBe)
   168  	XORQ(rCo, rDu)
   169  	MOVQ(iState.Offset(_ki), rBi)
   170  	MOVQ(iState.Offset(_mo), rBo)
   171  	MOVQ(iState.Offset(_su), rBu)
   172  	XORQ(rDe, rBe)
   173  	ROLQ(Imm(44), rBe)
   174  	XORQ(rDi, rBi)
   175  	XORQ(rDa, rBa)
   176  	ROLQ(Imm(43), rBi)
   177  
   178  	MOVQ(rBe, rCa)
   179  	MOVQ(rc, rT1)
   180  	ORQ(rBi, rCa)
   181  	XORQ(rBa, rT1)
   182  	XORQ(rT1, rCa)
   183  	MOVQ(rCa, oState.Offset(_ba))
   184  
   185  	XORQ(rDu, rBu)
   186  	ROLQ(Imm(14), rBu)
   187  	MOVQ(rBa, rCu)
   188  	ANDQ(rBe, rCu)
   189  	XORQ(rBu, rCu)
   190  	MOVQ(rCu, oState.Offset(_bu))
   191  
   192  	XORQ(rDo, rBo)
   193  	ROLQ(Imm(21), rBo)
   194  	MOVQ(rBo, rT1)
   195  	ANDQ(rBu, rT1)
   196  	XORQ(rBi, rT1)
   197  	MOVQ(rT1, oState.Offset(_bi))
   198  
   199  	NOTQ(rBi)
   200  	ORQ(rBa, rBu)
   201  	ORQ(rBo, rBi)
   202  	XORQ(rBo, rBu)
   203  	XORQ(rBe, rBi)
   204  	MOVQ(rBu, oState.Offset(_bo))
   205  	MOVQ(rBi, oState.Offset(_be))
   206  	B_RBI_RCE()
   207  
   208  	Comment("Result g")
   209  	MOVQ(iState.Offset(_gu), rBe)
   210  	XORQ(rDu, rBe)
   211  	MOVQ(iState.Offset(_ka), rBi)
   212  	ROLQ(Imm(20), rBe)
   213  	XORQ(rDa, rBi)
   214  	ROLQ(Imm(3), rBi)
   215  	MOVQ(iState.Offset(_bo), rBa)
   216  	MOVQ(rBe, rT1)
   217  	ORQ(rBi, rT1)
   218  	XORQ(rDo, rBa)
   219  	MOVQ(iState.Offset(_me), rBo)
   220  	MOVQ(iState.Offset(_si), rBu)
   221  	ROLQ(Imm(28), rBa)
   222  	XORQ(rBa, rT1)
   223  	MOVQ(rT1, oState.Offset(_ga))
   224  	G_RT1_RCA()
   225  
   226  	XORQ(rDe, rBo)
   227  	ROLQ(Imm(45), rBo)
   228  	MOVQ(rBi, rT1)
   229  	ANDQ(rBo, rT1)
   230  	XORQ(rBe, rT1)
   231  	MOVQ(rT1, oState.Offset(_ge))
   232  	G_RT1_RCE()
   233  
   234  	XORQ(rDi, rBu)
   235  	ROLQ(Imm(61), rBu)
   236  	MOVQ(rBu, rT1)
   237  	ORQ(rBa, rT1)
   238  	XORQ(rBo, rT1)
   239  	MOVQ(rT1, oState.Offset(_go))
   240  
   241  	ANDQ(rBe, rBa)
   242  	XORQ(rBu, rBa)
   243  	MOVQ(rBa, oState.Offset(_gu))
   244  	NOTQ(rBu)
   245  	G_RBA_RCU()
   246  
   247  	ORQ(rBu, rBo)
   248  	XORQ(rBi, rBo)
   249  	MOVQ(rBo, oState.Offset(_gi))
   250  
   251  	Comment("Result k")
   252  	MOVQ(iState.Offset(_be), rBa)
   253  	MOVQ(iState.Offset(_gi), rBe)
   254  	MOVQ(iState.Offset(_ko), rBi)
   255  	MOVQ(iState.Offset(_mu), rBo)
   256  	MOVQ(iState.Offset(_sa), rBu)
   257  	XORQ(rDi, rBe)
   258  	ROLQ(Imm(6), rBe)
   259  	XORQ(rDo, rBi)
   260  	ROLQ(Imm(25), rBi)
   261  	MOVQ(rBe, rT1)
   262  	ORQ(rBi, rT1)
   263  	XORQ(rDe, rBa)
   264  	ROLQ(Imm(1), rBa)
   265  	XORQ(rBa, rT1)
   266  	MOVQ(rT1, oState.Offset(_ka))
   267  	K_RT1_RCA()
   268  
   269  	XORQ(rDu, rBo)
   270  	ROLQ(Imm(8), rBo)
   271  	MOVQ(rBi, rT1)
   272  	ANDQ(rBo, rT1)
   273  	XORQ(rBe, rT1)
   274  	MOVQ(rT1, oState.Offset(_ke))
   275  	K_RT1_RCE()
   276  
   277  	XORQ(rDa, rBu)
   278  	ROLQ(Imm(18), rBu)
   279  	NOTQ(rBo)
   280  	MOVQ(rBo, rT1)
   281  	ANDQ(rBu, rT1)
   282  	XORQ(rBi, rT1)
   283  	MOVQ(rT1, oState.Offset(_ki))
   284  
   285  	MOVQ(rBu, rT1)
   286  	ORQ(rBa, rT1)
   287  	XORQ(rBo, rT1)
   288  	MOVQ(rT1, oState.Offset(_ko))
   289  
   290  	ANDQ(rBe, rBa)
   291  	XORQ(rBu, rBa)
   292  	MOVQ(rBa, oState.Offset(_ku))
   293  	K_RBA_RCU()
   294  
   295  	Comment("Result m")
   296  	MOVQ(iState.Offset(_ga), rBe)
   297  	XORQ(rDa, rBe)
   298  	MOVQ(iState.Offset(_ke), rBi)
   299  	ROLQ(Imm(36), rBe)
   300  	XORQ(rDe, rBi)
   301  	MOVQ(iState.Offset(_bu), rBa)
   302  	ROLQ(Imm(10), rBi)
   303  	MOVQ(rBe, rT1)
   304  	MOVQ(iState.Offset(_mi), rBo)
   305  	ANDQ(rBi, rT1)
   306  	XORQ(rDu, rBa)
   307  	MOVQ(iState.Offset(_so), rBu)
   308  	ROLQ(Imm(27), rBa)
   309  	XORQ(rBa, rT1)
   310  	MOVQ(rT1, oState.Offset(_ma))
   311  	M_RT1_RCA()
   312  
   313  	XORQ(rDi, rBo)
   314  	ROLQ(Imm(15), rBo)
   315  	MOVQ(rBi, rT1)
   316  	ORQ(rBo, rT1)
   317  	XORQ(rBe, rT1)
   318  	MOVQ(rT1, oState.Offset(_me))
   319  	M_RT1_RCE()
   320  
   321  	XORQ(rDo, rBu)
   322  	ROLQ(Imm(56), rBu)
   323  	NOTQ(rBo)
   324  	MOVQ(rBo, rT1)
   325  	ORQ(rBu, rT1)
   326  	XORQ(rBi, rT1)
   327  	MOVQ(rT1, oState.Offset(_mi))
   328  
   329  	ORQ(rBa, rBe)
   330  	XORQ(rBu, rBe)
   331  	MOVQ(rBe, oState.Offset(_mu))
   332  
   333  	ANDQ(rBa, rBu)
   334  	XORQ(rBo, rBu)
   335  	MOVQ(rBu, oState.Offset(_mo))
   336  	M_RBE_RCU()
   337  
   338  	Comment("Result s")
   339  	MOVQ(iState.Offset(_bi), rBa)
   340  	MOVQ(iState.Offset(_go), rBe)
   341  	MOVQ(iState.Offset(_ku), rBi)
   342  	XORQ(rDi, rBa)
   343  	MOVQ(iState.Offset(_ma), rBo)
   344  	ROLQ(Imm(62), rBa)
   345  	XORQ(rDo, rBe)
   346  	MOVQ(iState.Offset(_se), rBu)
   347  	ROLQ(Imm(55), rBe)
   348  
   349  	XORQ(rDu, rBi)
   350  	MOVQ(rBa, rDu)
   351  	XORQ(rDe, rBu)
   352  	ROLQ(Imm(2), rBu)
   353  	ANDQ(rBe, rDu)
   354  	XORQ(rBu, rDu)
   355  	MOVQ(rDu, oState.Offset(_su))
   356  
   357  	ROLQ(Imm(39), rBi)
   358  	S_RDU_RCU()
   359  	NOTQ(rBe)
   360  	XORQ(rDa, rBo)
   361  	MOVQ(rBe, rDa)
   362  	ANDQ(rBi, rDa)
   363  	XORQ(rBa, rDa)
   364  	MOVQ(rDa, oState.Offset(_sa))
   365  	S_RDA_RCA()
   366  
   367  	ROLQ(Imm(41), rBo)
   368  	MOVQ(rBi, rDe)
   369  	ORQ(rBo, rDe)
   370  	XORQ(rBe, rDe)
   371  	MOVQ(rDe, oState.Offset(_se))
   372  	S_RDE_RCE()
   373  
   374  	MOVQ(rBo, rDi)
   375  	MOVQ(rBu, rDo)
   376  	ANDQ(rBu, rDi)
   377  	ORQ(rBa, rDo)
   378  	XORQ(rBi, rDi)
   379  	XORQ(rBo, rDo)
   380  	MOVQ(rDi, oState.Offset(_si))
   381  	MOVQ(rDo, oState.Offset(_so))
   382  }
   383  
   384  // keccakF1600 applies the Keccak permutation to a 1600b-wide
   385  // state represented as a slice of 25 uint64s.
   386  func keccakF1600() {
   387  	Implement("keccakF1600")
   388  	AllocLocal(200)
   389  
   390  	Load(Param("a"), rpState.Base)
   391  
   392  	Comment("Convert the user state into an internal state")
   393  	NOTQ(rpState.Offset(_be))
   394  	NOTQ(rpState.Offset(_bi))
   395  	NOTQ(rpState.Offset(_go))
   396  	NOTQ(rpState.Offset(_ki))
   397  	NOTQ(rpState.Offset(_mi))
   398  	NOTQ(rpState.Offset(_sa))
   399  
   400  	Comment("Execute the KeccakF permutation")
   401  	MOVQ(rpState.Offset(_ba), rCa)
   402  	MOVQ(rpState.Offset(_be), rCe)
   403  	MOVQ(rpState.Offset(_bu), rCu)
   404  
   405  	XORQ(rpState.Offset(_ga), rCa)
   406  	XORQ(rpState.Offset(_ge), rCe)
   407  	XORQ(rpState.Offset(_gu), rCu)
   408  
   409  	XORQ(rpState.Offset(_ka), rCa)
   410  	XORQ(rpState.Offset(_ke), rCe)
   411  	XORQ(rpState.Offset(_ku), rCu)
   412  
   413  	XORQ(rpState.Offset(_ma), rCa)
   414  	XORQ(rpState.Offset(_me), rCe)
   415  	XORQ(rpState.Offset(_mu), rCu)
   416  
   417  	XORQ(rpState.Offset(_sa), rCa)
   418  	XORQ(rpState.Offset(_se), rCe)
   419  	MOVQ(rpState.Offset(_si), rDi)
   420  	MOVQ(rpState.Offset(_so), rDo)
   421  	XORQ(rpState.Offset(_su), rCu)
   422  
   423  	for i, rc := range RoundConstants[:len(RoundConstants)-1] {
   424  		var iState, oState Mem
   425  		if i%2 == 0 {
   426  			iState, oState = rpState, rpStack
   427  		} else {
   428  			iState, oState = rpStack, rpState
   429  		}
   430  		mKeccakRound(iState, oState, U64(rc), MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
   431  	}
   432  	mKeccakRound(rpStack, rpState, U64(RoundConstants[len(RoundConstants)-1]), NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP)
   433  
   434  	Comment("Revert the internal state to the user state")
   435  	NOTQ(rpState.Offset(_be))
   436  	NOTQ(rpState.Offset(_bi))
   437  	NOTQ(rpState.Offset(_go))
   438  	NOTQ(rpState.Offset(_ki))
   439  	NOTQ(rpState.Offset(_mi))
   440  	NOTQ(rpState.Offset(_sa))
   441  
   442  	RET()
   443  }
   444  

View as plain text