Documentation ¶
Overview ¶
Package xoodyak implements the Xoodyak cryptographic suite. Xoodyak is the Cyclist operating mode utilizing the Xoodoo state permutation function to power a collection of building block functions. All functions described in the Xoodyak specification are implemented in this package: https://eprint.iacr.org/2018/767.pdf Xoodyak can operate in one of two modes: hashing or keyed mode which is configured as part of the Xoodyak object. Some functions are only available in one particular mode and will panic if invoked while Xoodyak is configured incorrectly. Using the Cyclist functions, Xoodyak can be configured into a variety of more standard cryptographic primitives such as:
- Hashing
- Message Authentication Code generation
- Authenticated Encryption
The hashing and AEAD primitives provided here are intended to be compatible with Xoodyak entry in NIST Lightweight Cryptography competition https://csrc.nist.gov/projects/lightweight-cryptography
Index ¶
- Constants
- func CryptoDecryptAEAD(in, key, id, ad, tag []byte) (pt []byte, valid bool, err error)
- func CryptoEncryptAEAD(in, key, id, ad []byte) (ct, tag []byte, err error)
- func HashXoodyak(in []byte) []byte
- func HashXoodyakLen(in []byte, hLen uint) []byte
- func MACXoodyak(key, msg []byte, macLen uint) []byte
- func NewXoodyakAEAD(key []byte) (cipher.AEAD, error)
- func NewXoodyakHash() hash.Hash
- func NewXoodyakMac(key []byte) hash.Hash
- type CryptMode
- type CyclistMode
- type CyclistPhase
- type Xoodyak
- func (xk *Xoodyak) Absorb(x []byte)
- func (xk *Xoodyak) AbsorbAny(x []byte, r uint, cd uint8)
- func (xk *Xoodyak) AbsorbBlock(x []byte, cd uint8)
- func (xk *Xoodyak) AbsorbKey(key, id, counter []byte)
- func (xk *Xoodyak) Crypt(msg []byte, cm CryptMode) []byte
- func (xk *Xoodyak) Decrypt(ct []byte) []byte
- func (xk *Xoodyak) Down(Xi []byte, Cd byte)
- func (xk *Xoodyak) Encrypt(pt []byte) []byte
- func (xk *Xoodyak) Ratchet()
- func (xk *Xoodyak) Squeeze(outLen uint) []byte
- func (xk *Xoodyak) SqueezeAny(YLen uint, Cu uint8) []byte
- func (xk *Xoodyak) SqueezeKey(keyLen uint) []byte
- func (xk *Xoodyak) Up(Cu byte, Yilen uint) []byte
Examples ¶
Constants ¶
Variables ¶
This section is empty.
Functions ¶
func CryptoDecryptAEAD ¶
CryptoDecryptAEAD decrypts and authenticates a ciphertext message given a 16-byte key, 16-byte nonce. optional associated metadata bytes, and a 16 byte authentication tag generated at encryption. A plaintext message is only returned if authentication is successful. This decryption process is compatible with the Xoodyak LWC AEAD implementation.
func CryptoEncryptAEAD ¶
CryptoEncryptAEAD encrypts a plaintext message given a 16-byte key, 16-bytes nonce, and optional associated metadata bytes. Along with a cipher text, a 16-byte authentication tag is also generated The ciphertext and tag data is compatible with the Xoodyak LWC AEAD implementation.
Example ¶
package main import ( "fmt" "strings" "github.com/inmcm/xoodoo/xoodyak" ) func main() { myMsg := []byte("hello xoodoo") // Normally, this is randomly generated and kept secret myKey := []byte{ 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, } // Normally, this is randomly generated and never repeated per key myNonce := []byte{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, } // Any sort of non-secret information about the plaintext or context of encryption myAD := []byte("33°59’39.51″N, 7°50’33.69″E") myCt, myTag, _ := xoodyak.CryptoEncryptAEAD(myMsg, myKey, myNonce, myAD) myPt, valid, _ := xoodyak.CryptoDecryptAEAD(myCt, myKey, myNonce, myAD, myTag) var output strings.Builder fmt.Fprintf(&output, "Msg:'%s'\n", myMsg) fmt.Fprintf(&output, "Key:%x\n", myKey) fmt.Fprintf(&output, "Nonce:%x\n", myNonce) fmt.Fprintf(&output, "Metadata:%x\n", myAD) fmt.Fprintf(&output, "Ciphertext:%x\n", myCt) fmt.Fprintf(&output, "AuthTag:%x\n", myTag) fmt.Fprintf(&output, "DecryptOK:%t\n", valid) fmt.Fprintf(&output, "Plaintext:'%s'", myPt) fmt.Println(output.String()) }
Output: Msg:'hello xoodoo' Key:0f0e0d0c0b0a09080706050403020100 Nonce:f0e1d2c3b4a5968778695a4b3c2d1e0f Metadata:3333c2b03539e2809933392e3531e280b34e2c2037c2b03530e2809933332e3639e280b345 Ciphertext:fffc82f88d8bb2ba4f38b85d AuthTag:6ef42d19830b3f0ecd784be7f4d10f46 DecryptOK:true Plaintext:'hello xoodoo'
func HashXoodyak ¶
HashXoodyak calculates a 32-byte hash on a provided slice of bytes. The output is compatible with the Xoodyak LWC definition
Example ¶
package main import ( "fmt" "github.com/inmcm/xoodoo/xoodyak" ) func main() { myMsg := []byte("hello xoodoo") myHash := xoodyak.HashXoodyak(myMsg) fmt.Printf("Msg:'%s'\nHash:%x\n", myMsg, myHash) }
Output: Msg:'hello xoodoo' Hash:5c9a95363d79b2157cbdfff49dddaf1f20562dc64644f2d28211478537e6b29a
func HashXoodyakLen ¶
HashXoodyakLen calculates a cryptographic hash of arbitrary length on a provided slice of bytes
Example ¶
package main import ( "fmt" "github.com/inmcm/xoodoo/xoodyak" ) func main() { myMsg := []byte("hello xoodoo") myHash := xoodyak.HashXoodyakLen(myMsg, 64) fmt.Printf("Msg:'%s'\nHash:%x\n", myMsg, myHash) }
Output: Msg:'hello xoodoo' Hash:5c9a95363d79b2157cbdfff49dddaf1f20562dc64644f2d28211478537e6b29a5675a6d4a3fe18b985e7ae018133c118a44c5f82b3672492a30408937e5712cb
func MACXoodyak ¶ added in v0.9.3
MACXoodyak generates a message authentication code of the desired length in bytes for the provided message based on the provided key data. This implements the MAC behavior described in section 1.3.2 of the Xoodyak specification.
Example ¶
package main import ( "fmt" "github.com/inmcm/xoodoo/xoodyak" ) func main() { myMsg := []byte("hello xoodoo") /* use a secret value here */ myKey := []byte("abcdefghijklmnop") myMac := xoodyak.MACXoodyak(myKey, myMsg, 32) fmt.Printf("Key:%x\nMsg:'%s'\nMAC:%x\n", myKey, myMsg, myMac) }
Output: Key:6162636465666768696a6b6c6d6e6f70 Msg:'hello xoodoo' MAC:57abf40d9927f0ed5e65ef5b57a3ecc2da46ebb4f3fc5346202056e2b24e6121
func NewXoodyakAEAD ¶
NewXoodyakAEAD accepts a set of key bytes and returns object compatible with the stdlib crypto/cipher AEAD interface
Example ¶
package main import ( "fmt" "log" "strings" "github.com/inmcm/xoodoo/xoodyak" ) func main() { myMsg := []byte("hello xoodoo") // Normally, this is randomly generated and kept secret myKey := []byte{ 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, } // Normally, this is randomly generated and never repeated per key myNonce := []byte{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, } // Any sort of non-secret data myAD := []byte("33°59’39.51″N, 7°50’33.69″E") myXkAEAD, _ := xoodyak.NewXoodyakAEAD(myKey) myAuthCt := myXkAEAD.Seal(nil, myNonce, myMsg, myAD) myPt, err := myXkAEAD.Open(nil, myNonce, myAuthCt, myAD) // error is returned on decrypt authentication failure if err != nil { log.Fatal(err) } var output strings.Builder fmt.Fprintf(&output, "Msg:'%s'\n", myMsg) fmt.Fprintf(&output, "Key:%x\n", myKey) fmt.Fprintf(&output, "Nonce:%x\n", myNonce) fmt.Fprintf(&output, "Metadata:%x\n", myAD) fmt.Fprintf(&output, "Authenticated Ciphertext:%x\n", myAuthCt) fmt.Fprintf(&output, "Plaintext:'%s'", myPt) fmt.Println(output.String()) }
Output: Msg:'hello xoodoo' Key:0f0e0d0c0b0a09080706050403020100 Nonce:f0e1d2c3b4a5968778695a4b3c2d1e0f Metadata:3333c2b03539e2809933392e3531e280b34e2c2037c2b03530e2809933332e3639e280b345 Authenticated Ciphertext:fffc82f88d8bb2ba4f38b85d6ef42d19830b3f0ecd784be7f4d10f46 Plaintext:'hello xoodoo'
func NewXoodyakHash ¶
NewXoodyakHash returns a initialized Xoodyak digest object compatible with the stdlib Hash interface
Example ¶
package main import ( "bytes" "fmt" "io" "github.com/inmcm/xoodoo/xoodyak" ) func main() { myMsg := []byte("hello xoodoo") msgBuf := bytes.NewBuffer(myMsg) xHash := xoodyak.NewXoodyakHash() io.Copy(xHash, msgBuf) myHash := xHash.Sum(nil) fmt.Printf("Msg:'%s'\nHash:%x\n", myMsg, myHash) }
Output: Msg:'hello xoodoo' Hash:5c9a95363d79b2157cbdfff49dddaf1f20562dc64644f2d28211478537e6b29a
func NewXoodyakMac ¶ added in v0.9.3
NewXoodyakMac generates a new hashing object with the provided key data already baked in. Writing Any data then written to the hash object is part of the MAC check. Note that the length of the resulting MAC matches that of the offical Xoodyak hash output: 32 bytes
Example ¶
package main import ( "fmt" "github.com/inmcm/xoodoo/xoodyak" ) func main() { myMsg := []byte("hello xoodoo") /* use a secret value here */ myKey := []byte("abcdefghijklmnop") newMac := xoodyak.NewXoodyakMac(myKey) newMac.Write(myMsg) myMac := newMac.Sum(nil) fmt.Printf("Key:%x\nMsg:'%s'\nMAC:%x\n", myKey, myMsg, myMac) }
Output: Key:6162636465666768696a6b6c6d6e6f70 Msg:'hello xoodoo' MAC:57abf40d9927f0ed5e65ef5b57a3ecc2da46ebb4f3fc5346202056e2b24e6121
Types ¶
type CryptMode ¶
type CryptMode int
CryptMode defines if a Xoodyak instance (already running in keyed mode) is encrypting or decrypting provided message data
type CyclistMode ¶
type CyclistMode int
CyclistMode defines if a Xoodyak instance should be running in hashing mode or encryption (keyed) modes
const ( Hash CyclistMode = iota + 1 Keyed )
type CyclistPhase ¶
type CyclistPhase int
CyclistPhase defines if a Xoodyak instance should perform the Up or Down method in the current Cyclist iteration
const ( Down CyclistPhase = iota + 1 Up )
type Xoodyak ¶
type Xoodyak struct { Instance *xoodoo.Xoodoo Mode CyclistMode Phase CyclistPhase AbsorbSize uint SqueezeSize uint }
Xoodyak is a cryptographic object that allows execution of the Cyclist operating mode on the Xoodoo permutation primitive. Xoodyak allows for construction of a variety of hashing, encryption and authentication schemes through assembly of its various operating methods
func Instantiate ¶
Instantiate generate a new Xoodoo object initialized for hashing or keyed operations
func (*Xoodyak) Absorb ¶
Absorb ingests a provided message at the rate of the Xoodyak instance's absorption size
func (*Xoodyak) AbsorbBlock ¶
AbsorbBlock ingests a single block of bytes encompassing a single iteration of the Cyclist sequence
func (*Xoodyak) AbsorbKey ¶
AbsorbKey is special Xoodyak method that ingests provided key, id (nonce), and counter messages into the Xoodoo state enabling the keyed mode of operation typically used for authenticated encryption
func (*Xoodyak) Crypt ¶
Crypt is core encryption function of Xoodyak/Cyclist. It accepts a byte message of arbitrary length and generates either a ciphertext or plaintext based on the mode provided. Encryption or decryption is accomplished via XOR against a keystream generated from the Xoodoo primitive
func (*Xoodyak) Decrypt ¶
Decrypt transforms the provided ciphertext message into a plainext message of equal size based on the Xoodyak instance provided (key, nonce, counter have already been processed)
func (*Xoodyak) Down ¶
Down injects the provided slice of bytes into the provided Xoodoo state via xor with the existing state
func (*Xoodyak) Encrypt ¶
Encrypt transforms the provided plaintext message into a ciphertext message of equal size based on the Xoodyak instance provided (key, nonce, counter have already been processed)
func (*Xoodyak) Ratchet ¶
func (xk *Xoodyak) Ratchet()
Ratchet performs a irreversible transformation of the underlying Xoodoo state to prevent key recovery
func (*Xoodyak) Squeeze ¶
Squeeze outputs a provided stream of pseudo-random bytes at the rate of the Xoodyak instance's squeeze size
func (*Xoodyak) SqueezeAny ¶
SqueezeAny allow generation of a message of pseudo-random bytes of any size based on permutating the underlying Xoodoo state
func (*Xoodyak) SqueezeKey ¶
SqueezeKey can generate a new encryption key from the existing Xoodyak state