keccakf_amd64_asm.mx raw

   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