Documentation ¶
Overview ¶
Package zuc implements ShangMi(SM) zuc stream cipher and integrity algorithm.
Index ¶
Examples ¶
Constants ¶
const ( IVSize128 = 16 IVSize256 = 23 )
const ( // number of words in a round RoundWords = 32 // number of bytes in a word WordSize = 4 WordMask = WordSize - 1 // number of bytes in a round RoundBytes = RoundWords * WordSize )
Variables ¶
This section is empty.
Functions ¶
func NewCipher ¶
func NewCipher(key, iv []byte) (cipher.SeekableStream, error)
NewCipher create a stream cipher based on key and iv aguments. The key must be 16 bytes long and iv must be 16 bytes long for zuc 128; or the key must be 32 bytes long and iv must be 23 bytes long for zuc 256; otherwise, an error will be returned.
Example ¶
package main import ( "crypto/rand" "encoding/hex" "fmt" "io" "github.com/emmansun/gmsm/zuc" ) func main() { // Load your secret key from a safe place and reuse it across multiple // NewCipher calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like bcrypt or scrypt. key, _ := hex.DecodeString("6368616e676520746869732070617373") plaintext := []byte("some plaintext") const ivSize = zuc.IVSize128 // The IV needs to be unique, but not secure. Therefore it's common to // include it at the beginning of the ciphertext. ciphertext := make([]byte, ivSize+len(plaintext)) iv := ciphertext[:ivSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { panic(err) } stream, err := zuc.NewCipher(key, iv) if err != nil { panic(err) } stream.XORKeyStream(ciphertext[ivSize:], plaintext) // It's important to remember that ciphertexts must be authenticated // (i.e. by using crypto/hmac) as well as being encrypted in order to // be secure. // Stream cipher is the same for both encryption and decryption, so we can // also decrypt that ciphertext with NewCTR. plaintext2 := make([]byte, len(plaintext)) stream, err = zuc.NewCipher(key, iv) if err != nil { panic(err) } stream.XORKeyStream(plaintext2, ciphertext[ivSize:]) fmt.Printf("%s\n", plaintext2) }
Output: some plaintext
Example (Zuc256) ¶
package main import ( "crypto/rand" "encoding/hex" "fmt" "io" "github.com/emmansun/gmsm/zuc" ) func main() { // Load your secret key from a safe place and reuse it across multiple // NewCipher calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like bcrypt or scrypt. key, _ := hex.DecodeString("6368616e6765207468697320706173736368616e676520746869732070617373") plaintext := []byte("some plaintext") const ivSize = zuc.IVSize256 // The IV needs to be unique, but not secure. Therefore it's common to // include it at the beginning of the ciphertext. ciphertext := make([]byte, ivSize+len(plaintext)) iv := ciphertext[:ivSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { panic(err) } stream, err := zuc.NewCipher(key, iv) if err != nil { panic(err) } stream.XORKeyStream(ciphertext[ivSize:], plaintext) // It's important to remember that ciphertexts must be authenticated // (i.e. by using crypto/hmac) as well as being encrypted in order to // be secure. // Stream cipher is the same for both encryption and decryption, so we can // also decrypt that ciphertext with NewCTR. plaintext2 := make([]byte, len(plaintext)) stream, err = zuc.NewCipher(key, iv) if err != nil { panic(err) } stream.XORKeyStream(plaintext2, ciphertext[ivSize:]) fmt.Printf("%s\n", plaintext2) }
Output: some plaintext
func NewEEACipher ¶
func NewEEACipher(key []byte, count, bearer, direction uint32) (cipher.SeekableStream, error)
NewEEACipher create a stream cipher based on key, count, bearer and direction arguments according specification. The key must be 16 bytes long and iv must be 16 bytes long, otherwise, an error will be returned. The count is the 32-bit counter value, the bearer is the 5-bit bearer identity and the direction is the 1-bit transmission direction flag.
Types ¶
type ZUC128Mac ¶
type ZUC128Mac struct {
// contains filtered or unexported fields
}
func NewEIAHash ¶
NewEIAHash create hash for zuc-128 eia, with arguments key, count, bearer and direction The key must be 16 bytes long and iv must be 16 bytes long, otherwise, an error will be returned. The count is the 32-bit counter value, the bearer is the 5-bit bearer identity and the direction is the 1-bit transmission direction flag.
func NewHash ¶
NewHash create hash for zuc-128 eia, with arguments key and iv. Both key/iv size are 16 in bytes.
Example ¶
package main import ( "encoding/hex" "fmt" "github.com/emmansun/gmsm/zuc" ) func main() { // Load your secret key from a safe place and reuse it across multiple // NewCipher calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like bcrypt or scrypt. key, _ := hex.DecodeString("6368616e676520746869732070617373") // iv should be generated randomly iv, _ := hex.DecodeString("6368616e676520746869732070617373") h, err := zuc.NewHash(key, iv) if err != nil { panic(err) } h.Write([]byte("hello world\n")) fmt.Printf("%x", h.Sum(nil)) }
Output: c43cd26a
func (*ZUC128Mac) Finish ¶
Finish this function hash nbits data in p and return mac value, after this function call, the hash state will be reset. In general, we will use byte level function, this is just for test/verify. nbits: number of bits to hash in p.
Example ¶
package main import ( "fmt" "github.com/emmansun/gmsm/zuc" ) func main() { key := make([]byte, 16) iv := make([]byte, 16) h, err := zuc.NewHash(key, iv) if err != nil { panic(err) } fmt.Printf("%x", h.Finish([]byte{0}, 1)) }
Output: c8a9595e
Example (Mixed) ¶
package main import ( "encoding/hex" "fmt" "github.com/emmansun/gmsm/zuc" ) func main() { key := []byte{ 0xc9, 0xe6, 0xce, 0xc4, 0x60, 0x7c, 0x72, 0xdb, 0x00, 0x0a, 0xef, 0xa8, 0x83, 0x85, 0xab, 0x0a, } // iv should be generated randomly iv, _ := hex.DecodeString("a94059da50000000294059da50008000") h, err := zuc.NewHash(key, iv) if err != nil { panic(err) } in, _ := hex.DecodeString("983b41d47d780c9e1ad11d7eb70391b1de0b35da2dc62f83e7b78d6306ca0ea07e941b7be91348f9fcb170e2217fecd97f9f68adb16e5d7d21e569d280ed775cebde3f4093c53881") h.Write(in) fmt.Printf("%x", h.Finish([]byte{0}, 1)) }
Output: fae8ff0b
type ZUC256Mac ¶
type ZUC256Mac struct {
// contains filtered or unexported fields
}
func NewHash256 ¶
NewHash256 create hash for zuc-256 eia, with arguments key, iv and tagSize. Key size is 32 in bytes, iv size is 23 in bytes, tagSize supports 4/8/16 in bytes. The larger the tag size, the worse the performance.
Example (TagSize16) ¶
package main import ( "encoding/hex" "fmt" "github.com/emmansun/gmsm/zuc" ) func main() { // Load your secret key from a safe place and reuse it across multiple // NewCipher calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like bcrypt or scrypt. key, _ := hex.DecodeString("6368616e6765207468697320706173736368616e676520746869732070617373") // iv should be generated randomly iv, _ := hex.DecodeString("6368616e6765207468697320706173736368616e676520") h, err := zuc.NewHash256(key, iv, 16) if err != nil { panic(err) } h.Write([]byte("hello world\n")) fmt.Printf("%x", h.Sum(nil)) }
Output: fd8d10ea65b6369cccc07d50b4657d84
Example (TagSize4) ¶
package main import ( "encoding/hex" "fmt" "github.com/emmansun/gmsm/zuc" ) func main() { // Load your secret key from a safe place and reuse it across multiple // NewCipher calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like bcrypt or scrypt. key, _ := hex.DecodeString("6368616e6765207468697320706173736368616e676520746869732070617373") // iv should be generated randomly iv, _ := hex.DecodeString("6368616e6765207468697320706173736368616e676520") h, err := zuc.NewHash256(key, iv, 4) if err != nil { panic(err) } h.Write([]byte("hello world\n")) fmt.Printf("%x", h.Sum(nil)) }
Output: b76f96ed
Example (TagSize8) ¶
package main import ( "encoding/hex" "fmt" "github.com/emmansun/gmsm/zuc" ) func main() { // Load your secret key from a safe place and reuse it across multiple // NewCipher calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like bcrypt or scrypt. key, _ := hex.DecodeString("6368616e6765207468697320706173736368616e676520746869732070617373") // iv should be generated randomly iv, _ := hex.DecodeString("6368616e6765207468697320706173736368616e676520") h, err := zuc.NewHash256(key, iv, 8) if err != nil { panic(err) } h.Write([]byte("hello world\n")) fmt.Printf("%x", h.Sum(nil)) }
Output: f28aea6c9db3dc69
func (*ZUC256Mac) Finish ¶
Finish this function hash nbits data in p and return mac value In general, we will use byte level function, this is just for test/verify.