// GenerateKey returns an appropriate private and public key pair // for securing messages. func GenerateKey() (priv *[PrivateKeySize]byte, pub *[PublicKeySize]byte, ok bool) { var priv1 [32]byte var priv2 [32]byte var pub1 [32]byte var pub2 [32]byte _, err := io.ReadFull(PRNG, priv1[:]) if err != nil { return } _, err = io.ReadFull(PRNG, priv2[:]) if err != nil { return } h := sha3.NewKeccak384() h.Write(priv1[:]) digest := h.Sum(nil) copy(priv1[:], digest) priv1[0] &= 248 priv1[31] &= 127 priv1[31] |= 64 h.Reset() h.Write(priv2[:]) digest = h.Sum(nil) copy(priv2[:], digest) priv2[0] &= 248 priv2[31] &= 127 priv2[31] |= 64 curve25519.ScalarBaseMult(&pub1, &priv1) curve25519.ScalarBaseMult(&pub2, &priv2) priv = new([PrivateKeySize]byte) copy(priv[:32], priv1[:]) copy(priv[32:], priv2[:]) pub = new([PublicKeySize]byte) copy(pub[:32], pub1[:]) copy(pub[32:], pub2[:]) secretbox.Zero(priv1[:]) secretbox.Zero(priv2[:]) ok = true return }
// SharedKey generates a secretbox key from a key exchange. Alice // receives Bob's public key, and uses her private key in conjunction // with Bob's public key to generate a suitable encryption key. In // practice, Alice actually receives an ephemeral public key from // Bob. This is handled automatically by Seal and Open, and should // only be used by protocols or applications that use a different key // exchange mechanism. func SharedKey(priv *[PrivateKeySize]byte, pub *[PublicKeySize]byte) *[secretbox.KeySize]byte { split := splitKeys(priv, pub) defer secretbox.Zero(split.priv1[:]) defer secretbox.Zero(split.priv2[:]) sk1 := sharedKey(&split.priv1, &split.pub1) sk2 := sharedKey(&split.priv2, &split.pub2) defer secretbox.Zero(sk1[:]) defer secretbox.Zero(sk2[:]) h := sha3.NewKeccak384() h.Write(sk2[:]) sk3 := h.Sum(nil) defer secretbox.Zero(sk3) var sk = new([secretbox.KeySize]byte) copy(sk[:32], sk1[:]) copy(sk[32:], sk3) return sk }
// getHash calculates the hash of a file. // It reads a file block by block, and updates a hashsum with each block. // Reading by blocks consume very little memory, which is needed for large files. // parameters: // - fd is an open file descriptor that points to the file to inspect // - hashType is an integer that define the type of hash // return: // - hexhash, the hex encoded hash of the file found at fp func getHash(fd *os.File, hashType int) (hexhash string) { if DEBUG { fmt.Printf("getHash: computing hash for '%s'\n", fd.Name()) } var h hash.Hash switch hashType { case CheckMD5: h = md5.New() case CheckSHA1: h = sha1.New() case CheckSHA256: h = sha256.New() case CheckSHA384: h = sha512.New384() case CheckSHA512: h = sha512.New() case CheckSHA3_224: h = sha3.NewKeccak224() case CheckSHA3_256: h = sha3.NewKeccak256() case CheckSHA3_384: h = sha3.NewKeccak384() case CheckSHA3_512: h = sha3.NewKeccak512() default: err := fmt.Sprintf("getHash: Unkown hash type %d", hashType) panic(err) } buf := make([]byte, 4096) var offset int64 = 0 for { block, err := fd.ReadAt(buf, offset) if err != nil && err != io.EOF { panic(err) } if block == 0 { break } h.Write(buf[:block]) offset += int64(block) } hexhash = fmt.Sprintf("%x", h.Sum(nil)) return }
func keccakMAC(key, in []byte) []byte { h := sha3.NewKeccak384() h.Write(key) h.Write(in) return h.Sum(nil) }