Threefish est un chiffrement par bloc modifiable qui a été développé dans le cadre de la fonction de hachage Skein en tant que soumission au concours de fonctions de hachage du NIST. Threefish prend en charge des tailles de bloc de 256, 512 et 1 024 bits.
La spécification complète de Threefish est disponible dans les notes de bas de page 1 .
Les vecteurs de test ont été extraits de la dernière implémentation de référence 2 .
Les boucles de chiffrement et de déchiffrement ont été déroulées pour contenir huit tours à chaque itération. Cela permet aux constantes de rotation d'être intégrées dans le code sans être répétées. Cette pratique est décrite en détail dans le document 1 qui fournit également des informations détaillées sur les performances.
Pour installer en tant que dépendance dans un projet go :
go get -U github.com/schultz-is/go-threefish
Les implémentations de chiffrement dans ce package remplissent l'interface crypto/cipher
cipher.Block
. Les instances renvoyées par cette bibliothèque peuvent être utilisées avec n'importe quel mode de chiffrement par bloc prenant en charge des tailles de bloc de 256, 512 ou 1 024 bits.
package main
import (
"crypto/cipher"
"crypto/rand"
"fmt"
"github.com/schultz-is/go-threefish"
)
func main () {
message := make ([] byte , 128 )
copy ( message , [] byte ( "secret message" ))
// Assign a key. Generally this is derived from a known secret value. Often
// a passphrase is derived using a key derivation function such as PBKDF2.
key := make ([] byte , 128 )
_ , err := rand . Read ( key )
if err != nil {
panic ( err )
}
// Assign a tweak value. This allows customization of the block cipher as in
// the UBI block chaining mode. Support for the tweak value is not available
// in the block ciphers modes supported by the standard library.
tweak := make ([] byte , 16 )
_ , err = rand . Read ( tweak )
if err != nil {
panic ( err )
}
// Instantiate and initialize a block cipher.
block , err := threefish . New1024 ( key , tweak )
if err != nil {
panic ( err )
}
// When using CBC mode, the IV needs to be unique but does not need to be
// secure. For this reason, it can be prepended to the ciphertext.
ciphertext := make ([] byte , block . BlockSize () + len ( message ))
iv := ciphertext [: block . BlockSize ()]
_ , err = rand . Read ( iv )
if err != nil {
panic ( err )
}
mode := cipher . NewCBCEncrypter ( block , iv )
mode . CryptBlocks ( ciphertext [ block . BlockSize ():], message )
fmt . Printf ( "%x n " , ciphertext )
}
Des tests unitaires peuvent être exécutés et la couverture des tests peut être visualisée via le Makefile fourni.
make test
make cover
Des benchmarks peuvent être exécutés et des profils de CPU et de mémoire peuvent être générés via le Makefile fourni.
make benchmark
go tool pprof cpu.prof
go tool pprof mem.prof
name time/op speed
Threefish256/encrypt-8 85 ns 372 MB/s
Threefish256/decrypt-8 111 ns 287 MB/s
Threefish512/encrypt-8 234 ns 272 MB/s
Threefish512/decrypt-8 363 ns 175 MB/s
Threefish1024/encrypt-8 581 ns 220 MB/s
Threefish1024/decrypt-8 685 ns 186 MB/s
name time/op speed
Threefish256/encrypt-16 124 ns 259 MB/s
Threefish256/decrypt-16 156 ns 206 MB/s
Threefish512/encrypt-16 338 ns 189 MB/s
Threefish512/decrypt-16 310 ns 206 MB/s
Threefish1024/encrypt-16 804 ns 159 MB/s
Threefish1024/decrypt-16 778 ns 165 MB/s
http://www.skein-hash.info/sites/default/files/skein1.3.pdf ↩ ↩ 2
http://www.skein-hash.info/sites/default/files/NIST_CD_102610.zip ↩