Initial commit.
This commit is contained in:
		
						commit
						ed04711f60
					
				
							
								
								
									
										3
									
								
								const.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								const.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| package keccak | ||||
| var RC = [24]uint64{0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008} | ||||
| var rotc = [5][5]uint{[5]uint{0x0, 0x24, 0x3, 0x29, 0x12}, [5]uint{0x1, 0x2c, 0xa, 0x2d, 0x2}, [5]uint{0x3e, 0x6, 0x2b, 0xf, 0x3d}, [5]uint{0x1c, 0x37, 0x19, 0x15, 0x38}, [5]uint{0x1b, 0x14, 0x27, 0x8, 0xe}} | ||||
							
								
								
									
										27
									
								
								genconst.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								genconst.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| // +build ignore | ||||
| 
 | ||||
| package main | ||||
| 
 | ||||
| import "fmt" | ||||
| 
 | ||||
| func main() { | ||||
| 	//Round constants | ||||
| 	var RC [24]uint64 | ||||
| 	rc := uint8(1) | ||||
| 	for i := 0; i < 24; i++ { | ||||
| 		for j := 0; j <= 6; j++ { | ||||
| 			RC[i] |= uint64(rc&1) << (1<<uint(j) - 1) | ||||
| 			rc = rc<<1 ^ 0x71&uint8(int8(rc)>>7) | ||||
| 		} | ||||
| 	} | ||||
| 	fmt.Println("package keccak") | ||||
| 	fmt.Printf("var RC = %#016v\n", RC) | ||||
| 
 | ||||
| 	var rot [5][5]uint | ||||
| 	x, y := 1, 0 | ||||
| 	for i := 0; i < 24; i++ { | ||||
| 		rot[x][y] = uint((i+1)*(i+2)/2)%64 | ||||
| 		x, y = y, (2*x+3*y)%5 | ||||
| 	} | ||||
| 	fmt.Printf("var rotc = %#v\n", rot) | ||||
| } | ||||
							
								
								
									
										70
									
								
								keccak.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								keccak.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | ||||
| package keccak | ||||
| 
 | ||||
| // roundGeneric implements one round of the keccak-f[1600] permutation. | ||||
| func roundGeneric(a [5][5]uint64) [5][5]uint64 { | ||||
| 	a = theta(a) | ||||
| 	a = rho(a) | ||||
| 	a = pi(a) | ||||
| 	a = chi(a) | ||||
| 	// Iota | ||||
| 	//a[0][0] ^= RC[i] | ||||
| 	return a | ||||
| } | ||||
| 
 | ||||
| // Theta | ||||
| func theta(a [5][5]uint64) [5][5]uint64 { | ||||
| 	var c [5]uint64 | ||||
| 	for x := range a { | ||||
| 		c[x] = a[x][0] ^ a[x][1] ^ a[x][2] ^ a[x][3] ^ a[x][4] | ||||
| 	} | ||||
| 	for x := range a { | ||||
| 		x0, x1 := (x+4)%5, (x+1)%5 | ||||
| 		a[x][0] ^= c[x0] ^ rotl(c[x1], 1) | ||||
| 		a[x][1] ^= c[x0] ^ rotl(c[x1], 1) | ||||
| 		a[x][2] ^= c[x0] ^ rotl(c[x1], 1) | ||||
| 		a[x][3] ^= c[x0] ^ rotl(c[x1], 1) | ||||
| 		a[x][4] ^= c[x0] ^ rotl(c[x1], 1) | ||||
| 	} | ||||
| 	return a | ||||
| } | ||||
| 
 | ||||
| // Rho | ||||
| func rho(a [5][5]uint64) [5][5]uint64 { | ||||
| 	for x := range a { | ||||
| 		for y := range a[0] { | ||||
| 			a[x][y] = rotl(a[x][y], rotc[x][y]) | ||||
| 		} | ||||
| 	} | ||||
| 	return a | ||||
| } | ||||
| 
 | ||||
| // Pi | ||||
| func pi(a [5][5]uint64) [5][5]uint64 { | ||||
| 	var b [5][5]uint64 | ||||
| 	for x := range a { | ||||
| 		for y := range a[0] { | ||||
| 			x0 := y | ||||
| 			y0 := (x*2 + y*3) % 5 | ||||
| 			b[x0][y0] = a[x][y] | ||||
| 		} | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
| 
 | ||||
| // Chi | ||||
| func chi(a [5][5]uint64) [5][5]uint64 { | ||||
| 	for y := range a[0] { | ||||
| 		c := [5]uint64{a[0][y], a[1][y], a[2][y], a[3][y], a[4][y]} | ||||
| 		a[0][y] ^= ^c[1] & c[2] | ||||
| 		a[1][y] ^= ^c[2] & c[3] | ||||
| 		a[2][y] ^= ^c[3] & c[4] | ||||
| 		a[3][y] ^= ^c[4] & c[0] | ||||
| 		a[4][y] ^= ^c[0] & c[1] | ||||
| 	} | ||||
| 	return a | ||||
| } | ||||
| 
 | ||||
| func rotl(a uint64, r uint) uint64 { | ||||
| 	return a<<r | a>>(64-r) | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										29
									
								
								keccak_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								keccak_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| package keccak | ||||
| 
 | ||||
| import ( | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| ) | ||||
| 
 | ||||
| var vector = []byte{0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c, | ||||
| 	0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, 0xc0, | ||||
| 	0xe5, 0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, | ||||
| 	0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, 0xa4, 0x70, | ||||
| } | ||||
| 
 | ||||
| func TestKeccak(t *testing.T) { | ||||
| 	h := New() | ||||
| 	sum := h.Sum(nil) | ||||
| 	if !reflect.DeepEqual(sum, vector) { | ||||
| 		t.Errorf("\"\": want % x, got % x", vector, sum) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func Benchmark256(b *testing.B) { | ||||
| 	var tmp [Size]byte | ||||
| 	h := New() | ||||
| 	b.SetBytes(BlockSize) | ||||
| 	for i := 0; i < b.N; i ++ { | ||||
| 		h.Sum(tmp[:]) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										87
									
								
								sponge.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								sponge.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | ||||
| package keccak | ||||
| 
 | ||||
| import "hash" | ||||
| 
 | ||||
| const Size = 256/8 | ||||
| 
 | ||||
| const BlockSize = 1600/8 - Size*2 | ||||
| 
 | ||||
| // digest implements hash.Hash | ||||
| type digest struct { | ||||
| 	a [5][5]uint64 | ||||
| 	buf [BlockSize]byte | ||||
| 	len int | ||||
| } | ||||
| 
 | ||||
| func New() hash.Hash { | ||||
| 	return &digest{} | ||||
| } | ||||
| 
 | ||||
| func (d *digest) Size() int { return Size } | ||||
| func (d *digest) BlockSize() int { return BlockSize } | ||||
| 
 | ||||
| func (d *digest) Reset() { | ||||
| 	*d = digest{} | ||||
| } | ||||
| 
 | ||||
| func (d *digest) Write(b []byte) (int, error) { | ||||
| 	written := len(b) | ||||
| 	for len(b) > 0 { | ||||
| 		n := copy(d.buf[d.len:], b) | ||||
| 		d.len += n | ||||
| 		b = b[n:] | ||||
| 		if d.len == BlockSize { | ||||
| 			d.flush() | ||||
| 		} | ||||
| 	} | ||||
| 	return written, nil | ||||
| } | ||||
| 
 | ||||
| func (d *digest) flush() { | ||||
| 	b := d.buf[:] | ||||
| loop: | ||||
| 	for y := range d.a[0] { | ||||
| 		for  x := range d.a { | ||||
| 			if len(b) == 0 { | ||||
| 				break loop | ||||
| 			} | ||||
| 			d.a[x][y] ^= uint64(b[0]) + uint64(b[1])<<8 + uint64(b[2])<<16 + uint64(b[3])<<24 + uint64(b[4])<<32 + uint64(b[5])<<40 + uint64(b[6])<<48 + uint64(b[7])<<56 | ||||
| 			b = b[8:] | ||||
| 		} | ||||
| 	} | ||||
| 	d.a = keccak(d.a) | ||||
| 	d.len = 0 | ||||
| } | ||||
| 
 | ||||
| func keccak(a [5][5]uint64) [5][5]uint64 { | ||||
| 	for i := 0; i < 24; i++ { | ||||
| 		a = roundGeneric(a) | ||||
| 		a[0][0] ^= RC[i] | ||||
| 	} | ||||
| 	return a | ||||
| } | ||||
| 
 | ||||
| func (d0 *digest) Sum(b []byte) []byte { | ||||
| 	d := *d0 | ||||
| 	d.buf[d.len] = 0x01 | ||||
| 	for i := d.len+1; i < BlockSize; i++ { | ||||
| 		d.buf[i] = 0 | ||||
| 	} | ||||
| 	d.buf[BlockSize-1] |= 0x80 | ||||
| 	d.flush() | ||||
| 
 | ||||
| 	b = le64enc(b, d.a[0][0]) | ||||
| 	b = le64enc(b, d.a[1][0]) | ||||
| 	b = le64enc(b, d.a[2][0]) | ||||
| 	b = le64enc(b, d.a[3][0]) | ||||
| 	return b | ||||
| } | ||||
| 
 | ||||
| func le64enc(b []byte, x uint64) []byte { | ||||
| 	return append(b, byte(x), byte(x>>8), byte(x>>16), byte(x>>24), byte(x>>32), byte(x>>40), byte(x>>48), byte(x>>56)) | ||||
| } | ||||
| 
 | ||||
| func (d *digest) writeByte(b byte) { | ||||
| 	var tmp = [1]byte{b} | ||||
| 	d.Write(tmp[:]) | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user