package main

import (
	"encoding/base64"

	crypthash "github.com/sergeymakinen/go-crypt/hash"
	"github.com/sergeymakinen/go-crypt/sha512"
)

// for some reason, no implementation of crypt's sha512 is clean enough :(

func sha512crypt(password, seed []byte) (string, error) {
	// loose salt entropy because of character restriction in the salt
	salt := []byte(base64.RawStdEncoding.EncodeToString(seed))[:sha512.MaxSaltLength]
	// - base64 allows '+' where the salt accepts '.'
	for i, c := range salt {
		if c == '+' {
			salt[i] = '.'
		}
	}

	scheme := struct {
		HashPrefix string
		Rounds     uint32 `hash:"param:rounds,omitempty"`
		Salt       []byte
		Sum        [86]byte
	}{
		HashPrefix: sha512.Prefix,
		Rounds:     sha512.DefaultRounds,
		Salt:       salt,
	}

	key, err := sha512.Key([]byte(password), scheme.Salt, scheme.Rounds)
	if err != nil {
		return "", err
	}
	crypthash.LittleEndianEncoding.Encode(scheme.Sum[:], key)
	return crypthash.Marshal(scheme)
}
