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

View as plain text