package  gcmimport  (	"crypto/internal/fips140/aes" 	"crypto/internal/fips140/subtle" 	"crypto/internal/fips140deps/cpu" 	"crypto/internal/impl" )func  gcmAesInit(productTable  *[256 ]byte , ks  []uint32 )func  gcmAesData(productTable  *[256 ]byte , data  []byte , T  *[16 ]byte )func  gcmAesEnc(productTable  *[256 ]byte , dst , src  []byte , ctr , T  *[16 ]byte , ks  []uint32 )func  gcmAesDec(productTable  *[256 ]byte , dst , src  []byte , ctr , T  *[16 ]byte , ks  []uint32 )func  gcmAesFinish(productTable  *[256 ]byte , tagMask , T  *[16 ]byte , pLen , dLen  uint64 )var  supportsAESGCM = cpu .X86HasAES  && cpu .X86HasPCLMULQDQ  && cpu .X86HasSSE41  && cpu .X86HasSSSE3  ||	cpu .ARM64HasAES  && cpu .ARM64HasPMULL func  init() {	if  cpu .AMD64  {		impl .Register ("gcm" , "AES-NI" , &supportsAESGCM )	}	if  cpu .ARM64  {		impl .Register ("gcm" , "Armv8.0" , &supportsAESGCM )	}}func  checkGenericIsExpected() {	if  supportsAESGCM  {		panic ("gcm: internal error: using generic implementation despite hardware support" )	}}type  gcmPlatformData struct  {	productTable [256 ]byte }func  initGCM(g  *GCM ) {	if  !supportsAESGCM  {		return 	}	gcmAesInit (&g .productTable , aes .EncryptionKeySchedule (&g .cipher ))}func  seal(out  []byte , g  *GCM , nonce , plaintext , data  []byte ) {	if  !supportsAESGCM  {		sealGeneric (out , g , nonce , plaintext , data )		return 	}	var  counter , tagMask  [gcmBlockSize ]byte 	if  len (nonce ) == gcmStandardNonceSize  {				copy (counter [:], nonce )		counter [gcmBlockSize -1 ] = 1 	} else  {				gcmAesData (&g .productTable , nonce , &counter )		gcmAesFinish (&g .productTable , &tagMask , &counter , uint64 (len (nonce )), uint64 (0 ))	}	aes .EncryptBlockInternal (&g .cipher , tagMask [:], counter [:])	var  tagOut  [gcmTagSize ]byte 	gcmAesData (&g .productTable , data , &tagOut )	if  len (plaintext ) > 0  {		gcmAesEnc (&g .productTable , out , plaintext , &counter , &tagOut , aes .EncryptionKeySchedule (&g .cipher ))	}	gcmAesFinish (&g .productTable , &tagMask , &tagOut , uint64 (len (plaintext )), uint64 (len (data )))	copy (out [len (plaintext ):], tagOut [:])}func  open(out  []byte , g  *GCM , nonce , ciphertext , data  []byte ) error  {	if  !supportsAESGCM  {		return  openGeneric (out , g , nonce , ciphertext , data )	}	tag  := ciphertext [len (ciphertext )-g .tagSize :]	ciphertext  = ciphertext [:len (ciphertext )-g .tagSize ]		var  counter , tagMask  [gcmBlockSize ]byte 	if  len (nonce ) == gcmStandardNonceSize  {				copy (counter [:], nonce )		counter [gcmBlockSize -1 ] = 1 	} else  {				gcmAesData (&g .productTable , nonce , &counter )		gcmAesFinish (&g .productTable , &tagMask , &counter , uint64 (len (nonce )), uint64 (0 ))	}	aes .EncryptBlockInternal (&g .cipher , tagMask [:], counter [:])	var  expectedTag  [gcmTagSize ]byte 	gcmAesData (&g .productTable , data , &expectedTag )	if  len (ciphertext ) > 0  {		gcmAesDec (&g .productTable , out , ciphertext , &counter , &expectedTag , aes .EncryptionKeySchedule (&g .cipher ))	}	gcmAesFinish (&g .productTable , &tagMask , &expectedTag , uint64 (len (ciphertext )), uint64 (len (data )))	if  subtle .ConstantTimeCompare (expectedTag [:g .tagSize ], tag ) != 1  {		return  errOpen 	}	return  nil } The pages are generated with Golds v0.7.9-preview . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .