github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-amcl/amcl/SHA3.go (about)

     1  /*
     2  Licensed to the Apache Software Foundation (ASF) under one
     3  or more contributor license agreements.  See the NOTICE file
     4  distributed with this work for additional information
     5  regarding copyright ownership.  The ASF licenses this file
     6  to you under the Apache License, Version 2.0 (the
     7  "License"); you may not use this file except in compliance
     8  with the License.  You may obtain a copy of the License at
     9  
    10    http://www.apache.org/licenses/LICENSE-2.0
    11  
    12  Unless required by applicable law or agreed to in writing,
    13  software distributed under the License is distributed on an
    14  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15  KIND, either express or implied.  See the License for the
    16  specific language governing permissions and limitations
    17  under the License.
    18  */
    19  
    20  /*
    21   * Implementation of the Secure Hashing Algorithm (SHA-384)
    22   *
    23   * Generates a 384 bit message digest. It should be impossible to come
    24   * come up with two messages that hash to the same value ("collision free").
    25   *
    26   * For use with byte-oriented messages only. 
    27   */
    28  
    29  //package main
    30  
    31  package amcl
    32  
    33  
    34  
    35  const SHA3_HASH224 int=28
    36  const SHA3_HASH256 int=32
    37  const SHA3_HASH384 int=48
    38  const SHA3_HASH512 int=64
    39  const SHA3_SHAKE128 int=16
    40  const SHA3_SHAKE256 int=32
    41  
    42  
    43  const sha3_ROUNDS int=24
    44  
    45  var sha3_RC = [24]uint64 {
    46  		0x0000000000000001,0x0000000000008082,0x800000000000808A,0x8000000080008000,
    47  		0x000000000000808B,0x0000000080000001,0x8000000080008081,0x8000000000008009,
    48  		0x000000000000008A,0x0000000000000088,0x0000000080008009,0x000000008000000A,
    49  		0x000000008000808B,0x800000000000008B,0x8000000000008089,0x8000000000008003,
    50  		0x8000000000008002,0x8000000000000080,0x000000000000800A,0x800000008000000A,
    51  		0x8000000080008081,0x8000000000008080,0x0000000080000001,0x8000000080008008}
    52  
    53  
    54  type SHA3 struct {
    55  	length uint64
    56  	rate int
    57  	len int
    58  	s [5][5] uint64
    59  }
    60  
    61  /* functions */
    62  
    63  func sha3_ROTL(x uint64,n uint64) uint64 {
    64  	return (((x)<<n) | ((x)>>(64-n)))
    65  }
    66  
    67  func (H *SHA3) transform() { /* basic transformation step */
    68  
    69  	var c [5]uint64
    70  	var d [5]uint64
    71  	var b [5][5]uint64
    72  
    73  	for k:=0;k<sha3_ROUNDS;k++ {
    74  		c[0]=H.s[0][0]^H.s[0][1]^H.s[0][2]^H.s[0][3]^H.s[0][4];
    75  		c[1]=H.s[1][0]^H.s[1][1]^H.s[1][2]^H.s[1][3]^H.s[1][4];
    76  		c[2]=H.s[2][0]^H.s[2][1]^H.s[2][2]^H.s[2][3]^H.s[2][4];
    77  		c[3]=H.s[3][0]^H.s[3][1]^H.s[3][2]^H.s[3][3]^H.s[3][4];
    78  		c[4]=H.s[4][0]^H.s[4][1]^H.s[4][2]^H.s[4][3]^H.s[4][4];
    79  
    80  		d[0]=c[4]^sha3_ROTL(c[1],1);
    81  		d[1]=c[0]^sha3_ROTL(c[2],1);
    82  		d[2]=c[1]^sha3_ROTL(c[3],1);
    83  		d[3]=c[2]^sha3_ROTL(c[4],1);
    84  		d[4]=c[3]^sha3_ROTL(c[0],1);
    85  
    86  		for i:=0;i<5;i++ {
    87  			for j:=0;j<5;j++ {
    88  					H.s[i][j]^=d[i];
    89  			}
    90  		}
    91  
    92  		b[0][0]=H.s[0][0];
    93  		b[1][3]=sha3_ROTL(H.s[0][1],36);
    94  		b[2][1]=sha3_ROTL(H.s[0][2],3);
    95  		b[3][4]=sha3_ROTL(H.s[0][3],41);
    96  		b[4][2]=sha3_ROTL(H.s[0][4],18);
    97  
    98  		b[0][2]=sha3_ROTL(H.s[1][0],1);
    99  		b[1][0]=sha3_ROTL(H.s[1][1],44);
   100  		b[2][3]=sha3_ROTL(H.s[1][2],10);
   101  		b[3][1]=sha3_ROTL(H.s[1][3],45);
   102  		b[4][4]=sha3_ROTL(H.s[1][4],2);
   103  
   104  		b[0][4]=sha3_ROTL(H.s[2][0],62);
   105  		b[1][2]=sha3_ROTL(H.s[2][1],6);
   106  		b[2][0]=sha3_ROTL(H.s[2][2],43);
   107  		b[3][3]=sha3_ROTL(H.s[2][3],15);
   108  		b[4][1]=sha3_ROTL(H.s[2][4],61);
   109  
   110  		b[0][1]=sha3_ROTL(H.s[3][0],28);
   111  		b[1][4]=sha3_ROTL(H.s[3][1],55);
   112  		b[2][2]=sha3_ROTL(H.s[3][2],25);
   113  		b[3][0]=sha3_ROTL(H.s[3][3],21);
   114  		b[4][3]=sha3_ROTL(H.s[3][4],56);
   115  
   116  		b[0][3]=sha3_ROTL(H.s[4][0],27);
   117  		b[1][1]=sha3_ROTL(H.s[4][1],20);
   118  		b[2][4]=sha3_ROTL(H.s[4][2],39);
   119  		b[3][2]=sha3_ROTL(H.s[4][3],8);
   120  		b[4][0]=sha3_ROTL(H.s[4][4],14);
   121  
   122  		for i:=0;i<5;i++ {
   123  			for j:=0;j<5;j++ {
   124  				H.s[i][j]=b[i][j]^(^b[(i+1)%5][j]&b[(i+2)%5][j]);
   125  			}
   126  		}
   127  
   128  		H.s[0][0]^=sha3_RC[k];
   129  	}
   130  } 
   131  
   132  /* Initialise Hash function */
   133  func (H *SHA3) Init(olen int) { 
   134  	for i:=0;i<5;i++ {
   135  		for j:=0;j<5;j++ {
   136  			H.s[i][j]=0;
   137  		}
   138  	}
   139  	H.length=0
   140  	H.len=olen
   141  	H.rate=200-2*olen
   142  }
   143  
   144  
   145  func NewSHA3(olen int) *SHA3 {
   146  	H:= new(SHA3)
   147  	H.Init(olen)
   148  	return H
   149  }
   150  
   151  /* process a single byte */
   152  func (H *SHA3) Process(byt byte) { /* process the next message byte */
   153  	cnt:=int(H.length%uint64(H.rate))
   154  	b:=cnt%8
   155  	cnt/=8
   156  	i:=cnt%5
   157  	j:=cnt/5
   158  	H.s[i][j]^=uint64(byt&0xff)<<uint(8*b);
   159  	H.length++;
   160  	if int(H.length%uint64(H.rate))==0 {
   161  		H.transform()
   162  	}
   163  }
   164  
   165  /* squeeze the sponge */
   166  func (H *SHA3) Squeeze(buff []byte,olen int) {
   167  //	olen:=len(buff)
   168  	done:=false
   169  	m:=0
   170  /* extract by columns */
   171  	for {
   172  		for j:=0;j<5;j++ {
   173  			for i:=0;i<5;i++ {
   174  				el:=H.s[i][j]
   175  				for k:=0;k<8;k++ {
   176  					buff[m]=byte(el&0xff)
   177  					m++
   178  					if m>=olen || (m%H.rate)==0 {
   179  						done=true
   180  						break
   181  					}
   182  					el>>=8;
   183  				}
   184  				if done {break}
   185  			}
   186  			if done {break}
   187  		}
   188  		if m>=olen {break}
   189  		done=false
   190  		H.transform()
   191  
   192  	}
   193  }
   194  
   195  /* Generate Hash */
   196  func (H *SHA3) Hash(hash []byte) { /* generate a SHA3 hash of appropriate size */
   197  	q:=H.rate-int(H.length%uint64(H.rate))
   198  	if q==1 {
   199  		H.Process(0x86)
   200  	} else {
   201  		H.Process(0x06)
   202  		for int(H.length%uint64(H.rate)) != (H.rate-1) {H.Process(0x00)}
   203  		H.Process(0x80)
   204  	}
   205  	H.Squeeze(hash,H.len);
   206  }
   207  
   208  func (H *SHA3) Shake(hash []byte,olen int) { /* generate a SHA3 hash of appropriate size */
   209  	q:=H.rate-int(H.length%uint64(H.rate))
   210  	if q==1 {
   211  		H.Process(0x9f)
   212  	} else {
   213  		H.Process(0x1f)
   214  		for int(H.length%uint64(H.rate))!=H.rate-1 {H.Process(0x00)}
   215  		H.Process(0x80)
   216  	}
   217  	H.Squeeze(hash,olen);
   218  }
   219  
   220  
   221  
   222  /* test program: should produce digest */
   223  //916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18
   224  //afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185
   225  //98be04516c04cc73593fef3ed0352ea9f6443942d6950e29a372a681c3deaf4535423709b02843948684e029010badcc0acd8303fc85fdad3eabf4f78cae165635f57afd28810fc2
   226  
   227  /*
   228  func main() {
   229  
   230  	test := []byte("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu")
   231  	var digest [172]byte
   232  
   233  	sh:=NewSHA3(SHA3_HASH256)
   234  	for i:=0;i<len(test);i++ {
   235  		sh.Process(test[i])
   236  	}	
   237  	sh.Hash(digest[:])    
   238  	for i:=0;i<32;i++ {fmt.Printf("%02x",digest[i])}
   239  	fmt.Printf("\n");
   240  
   241  	sh=NewSHA3(SHA3_HASH512)
   242  	for i:=0;i<len(test);i++ {
   243  		sh.Process(test[i])
   244  	}	
   245  	sh.Hash(digest[:])    
   246  	for i:=0;i<64;i++ {fmt.Printf("%02x",digest[i])}
   247  	fmt.Printf("\n");
   248  
   249  	sh=NewSHA3(SHA3_SHAKE256)
   250  	for i:=0;i<len(test);i++ {
   251  		sh.Process(test[i])
   252  	}	
   253  	sh.Shake(digest[:],72)    
   254  	for i:=0;i<72;i++ {fmt.Printf("%02x",digest[i])}
   255  	fmt.Printf("\n");
   256  
   257  } */
   258