Rewrite CLI, go mod vendor
This commit is contained in:
parent
7cbef79fd2
commit
0a6e6bbcf8
|
@ -6,7 +6,6 @@ import (
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/subtle"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
|
@ -17,6 +16,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/HACKERALERT/infectious"
|
"github.com/HACKERALERT/infectious"
|
||||||
"github.com/HACKERALERT/serpent"
|
"github.com/HACKERALERT/serpent"
|
||||||
|
@ -29,6 +29,240 @@ import (
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var f *bool
|
||||||
|
var k *bool
|
||||||
|
var p *bool
|
||||||
|
var r *bool
|
||||||
|
var mode string
|
||||||
|
|
||||||
|
func parse() int {
|
||||||
|
flag.Usage = func() {
|
||||||
|
fmt.Println("Usage: picocrypt <item1> [<item2> ...]")
|
||||||
|
fmt.Println("Items: can be files, folders, or globs")
|
||||||
|
fmt.Println("Flags:")
|
||||||
|
flag.PrintDefaults()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
f = flag.Bool("f", false, "(decryption) attempt to fix corruption")
|
||||||
|
k = flag.Bool("k", false, "(decryption) keep output unconditionally")
|
||||||
|
p = flag.Bool("p", false, "(encryption) use paranoid mode")
|
||||||
|
r = flag.Bool("r", false, "(encryption) encode with Reed-Solomon")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if flag.NArg() == 0 {
|
||||||
|
flag.Usage()
|
||||||
|
}
|
||||||
|
for _, v := range flag.Args() {
|
||||||
|
if strings.HasPrefix(v, "-") {
|
||||||
|
fmt.Println("Flags must be provided before arguments!")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if flag.NArg() == 1 {
|
||||||
|
if strings.HasSuffix(flag.Arg(0), ".pcv") {
|
||||||
|
mode = "decrypt"
|
||||||
|
} else {
|
||||||
|
mode = "encrypt"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mode = "encrypt"
|
||||||
|
for _, v := range flag.Args() {
|
||||||
|
if strings.HasSuffix(v, ".pcv") {
|
||||||
|
fmt.Println("Multiple items must not contain volumes.")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var password []byte
|
||||||
|
var confirmp []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
func auth() int {
|
||||||
|
if mode == "encrypt" {
|
||||||
|
fmt.Print("Password: ")
|
||||||
|
password, err = term.ReadPassword(int(os.Stdin.Fd()))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error reading password!")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fmt.Print(strings.Repeat("*", len(password)), " | Confirm: ")
|
||||||
|
confirmp, err = term.ReadPassword(int(os.Stdin.Fd()))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error reading password!")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fmt.Println(strings.Repeat("*", len(confirmp)))
|
||||||
|
if !bytes.Equal(password, confirmp) {
|
||||||
|
fmt.Println("Passwords don't match!")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Print("Password: ")
|
||||||
|
password, err = term.ReadPassword(int(os.Stdin.Fd()))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error reading password!")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fmt.Println(strings.Repeat("*", len(password)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var pin string
|
||||||
|
var pout string
|
||||||
|
var pzip string
|
||||||
|
var file *os.File
|
||||||
|
var writer *zip.Writer
|
||||||
|
var files []string
|
||||||
|
var interrupted bool
|
||||||
|
|
||||||
|
func prepare() int {
|
||||||
|
if mode == "decrypt" {
|
||||||
|
pin = flag.Arg(0)
|
||||||
|
pout = strings.TrimSuffix(pin, ".pcv")
|
||||||
|
} else {
|
||||||
|
stat, err := os.Stat(flag.Arg(0))
|
||||||
|
if flag.NArg() == 1 && err == nil && !stat.IsDir() {
|
||||||
|
pin = flag.Arg(0)
|
||||||
|
pout = pin + ".pcv"
|
||||||
|
} else {
|
||||||
|
items := []string{}
|
||||||
|
for _, v := range flag.Args() {
|
||||||
|
if strings.Contains(v, "../") || strings.HasPrefix(v, "/") {
|
||||||
|
fmt.Println("Cannot encrypt outside of current directory.")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
matches, err := filepath.Glob(v)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Invalid glob pattern:", v)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
items = append(items, matches...)
|
||||||
|
}
|
||||||
|
for _, v := range items {
|
||||||
|
stat, err := os.Stat(v)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Cannot access input:", v)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if !stat.IsDir() {
|
||||||
|
files = append(files, v)
|
||||||
|
} else {
|
||||||
|
filepath.Walk(v, func(path string, _ os.FileInfo, _ error) error {
|
||||||
|
stat, err := os.Stat(path)
|
||||||
|
if err == nil && !stat.IsDir() {
|
||||||
|
files = append(files, path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(files) == 0 {
|
||||||
|
fmt.Println("Nothing to encrypt!")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func compress() int {
|
||||||
|
if files == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Cannot get current working directory!")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
dir = filepath.ToSlash(dir)
|
||||||
|
file, err = os.CreateTemp("", "picocrypt-cli-v2-*.tmp")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Cannot create temporary file!")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
pzip = file.Name()
|
||||||
|
writer = zip.NewWriter(file)
|
||||||
|
|
||||||
|
for i, path := range files {
|
||||||
|
stat, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
header, err := zip.FileInfoHeader(stat)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
abs, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
abs = filepath.ToSlash(abs)
|
||||||
|
header.Name = strings.TrimPrefix(abs, dir)
|
||||||
|
header.Name = strings.TrimPrefix(header.Name, "/")
|
||||||
|
header.Method = zip.Deflate
|
||||||
|
entry, err := writer.CreateHeader(header)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fin, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
writer.Close()
|
||||||
|
file.Close()
|
||||||
|
fmt.Println("Read access to input denied:", path)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
bar := progressbar.NewOptions(
|
||||||
|
int(stat.Size()),
|
||||||
|
progressbar.OptionClearOnFinish(),
|
||||||
|
progressbar.OptionFullWidth(),
|
||||||
|
progressbar.OptionShowBytes(true),
|
||||||
|
progressbar.OptionUseIECUnits(true),
|
||||||
|
progressbar.OptionSetDescription(
|
||||||
|
fmt.Sprintf("Compressing [%d/%d]:", i+1, len(files)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
_, err = io.Copy(io.MultiWriter(entry, bar), fin)
|
||||||
|
fin.Close()
|
||||||
|
if err != nil {
|
||||||
|
if interrupted {
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
} else {
|
||||||
|
writer.Close()
|
||||||
|
file.Close()
|
||||||
|
fmt.Println("Insufficient disk space!")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.Close()
|
||||||
|
file.Close()
|
||||||
|
pin = file.Name()
|
||||||
|
pout = "encrypted-" + strconv.Itoa(int(time.Now().Unix())) + ".zip.pcv"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var fin *os.File
|
||||||
|
var fout *os.File
|
||||||
|
var padded bool
|
||||||
|
var salt []byte
|
||||||
|
var hkdfSalt []byte
|
||||||
|
var serpentIV []byte
|
||||||
|
var nonce []byte
|
||||||
|
var keyHash []byte
|
||||||
|
var keyHashRef []byte
|
||||||
|
var authTag []byte
|
||||||
|
var key []byte
|
||||||
|
var mac hash.Hash
|
||||||
var MiB = 1 << 20
|
var MiB = 1 << 20
|
||||||
var GiB = 1 << 30
|
var GiB = 1 << 30
|
||||||
var rs5, _ = infectious.NewFEC(5, 15)
|
var rs5, _ = infectious.NewFEC(5, 15)
|
||||||
|
@ -77,370 +311,144 @@ func unpad(data []byte) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func work() int {
|
func work() int {
|
||||||
flag.Usage = func() {
|
fin, err = os.Open(pin)
|
||||||
fmt.Println("Usage: picocrypt [-p]aranoid [-r]eedsolo <item1> [<item2> ...]")
|
|
||||||
fmt.Println("Items: can be a file (cat.png), folder (./src), or glob (*.txt)")
|
|
||||||
}
|
|
||||||
paranoid := flag.Bool("p", false, "")
|
|
||||||
reedsolo := flag.Bool("r", false, "")
|
|
||||||
fix := flag.Bool("f", false, "")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
mode := ""
|
|
||||||
if flag.NArg() == 0 {
|
|
||||||
flag.Usage()
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if flag.NArg() == 1 {
|
|
||||||
if strings.HasSuffix(flag.Arg(0), ".pcv") {
|
|
||||||
mode = "decrypt"
|
|
||||||
} else {
|
|
||||||
mode = "encrypt"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mode = "encrypt"
|
|
||||||
for _, v := range flag.Args() {
|
|
||||||
if strings.HasSuffix(v, ".pcv") {
|
|
||||||
fmt.Println("Multiple items cannot contain volumes.")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, v := range flag.Args() {
|
|
||||||
if v == "-p" || v == "-r" || v == "-f" {
|
|
||||||
fmt.Println("Flags are only accepted before arguments!")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var password, cpassword []byte
|
|
||||||
var err error
|
|
||||||
if mode == "encrypt" {
|
|
||||||
fmt.Print("Password: ")
|
|
||||||
password, err = term.ReadPassword(int(os.Stdin.Fd()))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error reading password.")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
fmt.Print(strings.Repeat("*", len(password)), " | Confirm: ")
|
|
||||||
cpassword, err = term.ReadPassword(int(os.Stdin.Fd()))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error reading password.")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
fmt.Println(strings.Repeat("*", len(cpassword)))
|
|
||||||
if !bytes.Equal(password, cpassword) {
|
|
||||||
fmt.Println("Passwords don't match.")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Print("Password: ")
|
|
||||||
password, err = term.ReadPassword(int(os.Stdin.Fd()))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error reading password.")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
fmt.Println(strings.Repeat("*", len(password)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fin_, fout_ := "", ""
|
|
||||||
if mode == "decrypt" {
|
|
||||||
fin_ = flag.Arg(0)
|
|
||||||
fout_ = strings.TrimSuffix(fin_, ".pcv")
|
|
||||||
} else {
|
|
||||||
stat, err := os.Stat(flag.Arg(0))
|
|
||||||
if flag.NArg() == 1 && err == nil && !stat.IsDir() {
|
|
||||||
fin_ = flag.Arg(0)
|
|
||||||
fout_ = fin_ + ".pcv"
|
|
||||||
} else {
|
|
||||||
items := []string{}
|
|
||||||
for _, v := range flag.Args() {
|
|
||||||
if strings.Contains(v, "../") || strings.HasPrefix(v, "/") {
|
|
||||||
fmt.Println("Cannot encrypt outside of current directory.")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
matches, err := filepath.Glob(v)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Invalid glob pattern(s).")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
items = append(items, matches...)
|
|
||||||
}
|
|
||||||
files := []string{}
|
|
||||||
for _, v := range items {
|
|
||||||
stat, err := os.Stat(v)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Cannot access input(s).")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
if !stat.IsDir() {
|
|
||||||
files = append(files, v)
|
|
||||||
} else {
|
|
||||||
filepath.Walk(v, func(path string, _ os.FileInfo, _ error) error {
|
|
||||||
stat, err := os.Stat(path)
|
|
||||||
if err == nil && !stat.IsDir() {
|
|
||||||
files = append(files, path)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(files) == 0 {
|
|
||||||
fmt.Println("Nothing to encrypt.")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
dir, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Cannot get current working directory.")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
file, err := os.CreateTemp("", "picocrypt-cli-v2-*.tmp")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Cannot create temporary file.")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
writer := zip.NewWriter(file)
|
|
||||||
|
|
||||||
for i, path := range files {
|
|
||||||
stat, err := os.Stat(path)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
header, err := zip.FileInfoHeader(stat)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
abs, err := filepath.Abs(path)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
abs = filepath.ToSlash(abs)
|
|
||||||
header.Name = strings.TrimPrefix(abs, filepath.ToSlash(dir))
|
|
||||||
header.Name = strings.TrimPrefix(header.Name, "/")
|
|
||||||
header.Method = zip.Deflate
|
|
||||||
entry, err := writer.CreateHeader(header)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fin, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
writer.Close()
|
|
||||||
file.Close()
|
|
||||||
os.Remove(file.Name())
|
|
||||||
fmt.Println("Read access to input(s) denied.")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
bar := progressbar.NewOptions(
|
|
||||||
int(stat.Size()),
|
|
||||||
progressbar.OptionClearOnFinish(),
|
|
||||||
progressbar.OptionFullWidth(),
|
|
||||||
progressbar.OptionShowBytes(true),
|
|
||||||
progressbar.OptionUseIECUnits(true),
|
|
||||||
progressbar.OptionSetDescription(
|
|
||||||
fmt.Sprintf("Compressing [%d/%d]:", i+1, len(files)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
_, err = io.Copy(io.MultiWriter(entry, bar), fin)
|
|
||||||
fin.Close()
|
|
||||||
if err != nil {
|
|
||||||
writer.Close()
|
|
||||||
file.Close()
|
|
||||||
os.Remove(file.Name())
|
|
||||||
fmt.Println("Insufficient disk space.")
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer.Close()
|
|
||||||
file.Close()
|
|
||||||
fin_ = file.Name()
|
|
||||||
fout_ = "encrypted.zip.pcv"
|
|
||||||
defer os.Remove(file.Name())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var padded bool
|
|
||||||
var salt []byte // Argon2 salt, 16 bytes
|
|
||||||
var hkdfSalt []byte // HKDF-SHA3 salt, 32 bytes
|
|
||||||
var serpentIV []byte // Serpent IV, 16 bytes
|
|
||||||
var nonce []byte // 24-byte XChaCha20 nonce
|
|
||||||
var keyHash []byte // SHA3-512 hash of encryption key
|
|
||||||
var keyHashRef []byte // Same as 'keyHash', but used for comparison
|
|
||||||
var authTag []byte // 64-byte authentication tag (BLAKE2b or HMAC-SHA3)
|
|
||||||
|
|
||||||
fin, err := os.Open(fin_)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error accessing input file.")
|
fmt.Println("Error accessing input file:", pin)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
_, err = os.Stat(fout_)
|
_, err = os.Stat(pout)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Println("Output file already exists.")
|
fmt.Println("Output file already exists!")
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
fout, err := os.Create(fout_)
|
fout, err = os.Create(pout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error creating output file.")
|
fmt.Println("Error creating output file:", pout)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
c := make(chan os.Signal, 1)
|
stat, err := os.Stat(pin)
|
||||||
signal.Notify(c, os.Interrupt)
|
|
||||||
go func() {
|
|
||||||
<-c
|
|
||||||
fin.Close()
|
|
||||||
fout.Close()
|
|
||||||
if err := os.Remove(fout.Name()); err == nil {
|
|
||||||
fmt.Print("\nSystem interrupt detected, cleaning up.")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
stat, err := os.Stat(fin_)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error accessing input file.")
|
fmt.Println("Error accessing input file:", pin)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
total := stat.Size()
|
total := stat.Size()
|
||||||
if mode == "decrypt" {
|
if mode == "decrypt" {
|
||||||
total -= 789
|
total -= 789
|
||||||
}
|
}
|
||||||
|
|
||||||
if mode == "encrypt" {
|
if mode == "encrypt" {
|
||||||
errs := make([]error, 11)
|
errs := make([]error, 10)
|
||||||
salt = make([]byte, 16)
|
salt = make([]byte, 16)
|
||||||
hkdfSalt = make([]byte, 32)
|
hkdfSalt = make([]byte, 32)
|
||||||
serpentIV = make([]byte, 16)
|
serpentIV = make([]byte, 16)
|
||||||
nonce = make([]byte, 24)
|
nonce = make([]byte, 24)
|
||||||
_, errs[0] = fout.Write(rsEncode(rs5, []byte("v1.34")))
|
_, errs[0] = fout.Write(rsEncode(rs5, []byte("v1.34")))
|
||||||
commentsLength := []byte(fmt.Sprintf("%05d", 0))
|
_, errs[1] = fout.Write(rsEncode(rs5, []byte("00000")))
|
||||||
_, errs[1] = fout.Write(rsEncode(rs5, commentsLength))
|
|
||||||
flags := make([]byte, 5)
|
flags := make([]byte, 5)
|
||||||
if *paranoid {
|
if *p {
|
||||||
flags[0] = 1
|
flags[0] = 1
|
||||||
}
|
}
|
||||||
if *reedsolo {
|
if *r {
|
||||||
flags[3] = 1
|
flags[3] = 1
|
||||||
}
|
}
|
||||||
if total%int64(MiB) >= int64(MiB)-128 {
|
if total%int64(MiB) >= int64(MiB)-128 {
|
||||||
flags[4] = 1
|
flags[4] = 1
|
||||||
}
|
}
|
||||||
_, errs[3] = fout.Write(rsEncode(rs5, flags))
|
_, errs[2] = fout.Write(rsEncode(rs5, flags))
|
||||||
rand.Read(salt)
|
rand.Read(salt)
|
||||||
rand.Read(hkdfSalt)
|
rand.Read(hkdfSalt)
|
||||||
rand.Read(serpentIV)
|
rand.Read(serpentIV)
|
||||||
rand.Read(nonce)
|
rand.Read(nonce)
|
||||||
_, errs[4] = fout.Write(rsEncode(rs16, salt))
|
_, errs[3] = fout.Write(rsEncode(rs16, salt))
|
||||||
_, errs[5] = fout.Write(rsEncode(rs32, hkdfSalt))
|
_, errs[4] = fout.Write(rsEncode(rs32, hkdfSalt))
|
||||||
_, errs[6] = fout.Write(rsEncode(rs16, serpentIV))
|
_, errs[5] = fout.Write(rsEncode(rs16, serpentIV))
|
||||||
_, errs[7] = fout.Write(rsEncode(rs24, nonce))
|
_, errs[6] = fout.Write(rsEncode(rs24, nonce))
|
||||||
_, errs[8] = fout.Write(make([]byte, 192))
|
_, errs[7] = fout.Write(make([]byte, 192))
|
||||||
_, errs[9] = fout.Write(make([]byte, 96))
|
_, errs[8] = fout.Write(make([]byte, 96))
|
||||||
_, errs[10] = fout.Write(make([]byte, 192))
|
_, errs[9] = fout.Write(make([]byte, 192))
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
os.Remove(fout_)
|
fmt.Println("Insufficient disk space!")
|
||||||
fmt.Println("Insufficient disk space.")
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errs := make([]error, 10)
|
errs := make([]error, 9)
|
||||||
version := make([]byte, 15)
|
version := make([]byte, 15)
|
||||||
fin.Read(version)
|
fin.Read(version)
|
||||||
_, errs[0] = rsDecode(rs5, version, !(*fix))
|
_, errs[0] = rsDecode(rs5, version, !(*f))
|
||||||
tmp := make([]byte, 15)
|
tmp := make([]byte, 15)
|
||||||
fin.Read(tmp)
|
fin.Read(tmp)
|
||||||
tmp, errs[1] = rsDecode(rs5, tmp, !(*fix))
|
tmp, errs[1] = rsDecode(rs5, tmp, !(*f))
|
||||||
commentsLength, _ := strconv.Atoi(string(tmp))
|
comments, _ := strconv.Atoi(string(tmp))
|
||||||
fin.Read(make([]byte, commentsLength*3))
|
fin.Read(make([]byte, comments*3))
|
||||||
total -= int64(commentsLength) * 3
|
total -= int64(comments) * 3
|
||||||
flags := make([]byte, 15)
|
flags := make([]byte, 15)
|
||||||
fin.Read(flags)
|
fin.Read(flags)
|
||||||
flags, errs[2] = rsDecode(rs5, flags, !(*fix))
|
flags, errs[2] = rsDecode(rs5, flags, !(*f))
|
||||||
*paranoid = flags[0] == 1
|
*p = flags[0] == 1
|
||||||
*reedsolo = flags[3] == 1
|
*r = flags[3] == 1
|
||||||
padded = flags[4] == 1
|
padded = flags[4] == 1
|
||||||
if flags[1] == 1 {
|
if flags[1] == 1 {
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
os.Remove(fout_)
|
fmt.Println("Keyfiles are not supported!")
|
||||||
fmt.Println("Keyfiles are not supported.")
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
salt = make([]byte, 48)
|
salt = make([]byte, 48)
|
||||||
fin.Read(salt)
|
fin.Read(salt)
|
||||||
salt, errs[3] = rsDecode(rs16, salt, !(*fix))
|
salt, errs[3] = rsDecode(rs16, salt, !(*f))
|
||||||
hkdfSalt = make([]byte, 96)
|
hkdfSalt = make([]byte, 96)
|
||||||
fin.Read(hkdfSalt)
|
fin.Read(hkdfSalt)
|
||||||
hkdfSalt, errs[4] = rsDecode(rs32, hkdfSalt, !(*fix))
|
hkdfSalt, errs[4] = rsDecode(rs32, hkdfSalt, !(*f))
|
||||||
serpentIV = make([]byte, 48)
|
serpentIV = make([]byte, 48)
|
||||||
fin.Read(serpentIV)
|
fin.Read(serpentIV)
|
||||||
serpentIV, errs[5] = rsDecode(rs16, serpentIV, !(*fix))
|
serpentIV, errs[5] = rsDecode(rs16, serpentIV, !(*f))
|
||||||
nonce = make([]byte, 72)
|
nonce = make([]byte, 72)
|
||||||
fin.Read(nonce)
|
fin.Read(nonce)
|
||||||
nonce, errs[6] = rsDecode(rs24, nonce, !(*fix))
|
nonce, errs[6] = rsDecode(rs24, nonce, !(*f))
|
||||||
keyHashRef = make([]byte, 192)
|
keyHashRef = make([]byte, 192)
|
||||||
fin.Read(keyHashRef)
|
fin.Read(keyHashRef)
|
||||||
keyHashRef, errs[7] = rsDecode(rs64, keyHashRef, !(*fix))
|
keyHashRef, errs[7] = rsDecode(rs64, keyHashRef, !(*f))
|
||||||
keyfileHashRef := make([]byte, 96)
|
fin.Read(make([]byte, 96))
|
||||||
fin.Read(keyfileHashRef)
|
|
||||||
_, errs[8] = rsDecode(rs32, keyfileHashRef, !(*fix))
|
|
||||||
authTag = make([]byte, 192)
|
authTag = make([]byte, 192)
|
||||||
fin.Read(authTag)
|
fin.Read(authTag)
|
||||||
authTag, errs[9] = rsDecode(rs64, authTag, !(*fix))
|
authTag, errs[8] = rsDecode(rs64, authTag, !(*f))
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
os.Remove(fout_)
|
fmt.Println("The volume header is irrecoverably damaged!")
|
||||||
fmt.Println("The volume header is irrecoverably damaged.")
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var key []byte
|
if *p {
|
||||||
if *paranoid {
|
key = argon2.IDKey(password, salt, 8, 1<<20, 8, 32)
|
||||||
key = argon2.IDKey(
|
|
||||||
password,
|
|
||||||
salt,
|
|
||||||
8,
|
|
||||||
1<<20,
|
|
||||||
8,
|
|
||||||
32,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
key = argon2.IDKey(
|
key = argon2.IDKey(password, salt, 4, 1<<20, 4, 32)
|
||||||
password,
|
|
||||||
salt,
|
|
||||||
4,
|
|
||||||
1<<20,
|
|
||||||
4,
|
|
||||||
32,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp := sha3.New512()
|
tmp := sha3.New512()
|
||||||
tmp.Write(key)
|
tmp.Write(key)
|
||||||
keyHash = tmp.Sum(nil)
|
keyHash = tmp.Sum(nil)
|
||||||
|
|
||||||
if mode == "decrypt" {
|
if mode == "decrypt" {
|
||||||
if subtle.ConstantTimeCompare(keyHash, keyHashRef) != 1 {
|
if !bytes.Equal(keyHash, keyHashRef) {
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
os.Remove(fout_)
|
fmt.Println("Incorrect password!")
|
||||||
fmt.Println("Incorrect password.")
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done, counter := 0, 0
|
done, counter := 0, 0
|
||||||
chacha, _ := chacha20.NewUnauthenticatedCipher(key, nonce)
|
chacha, _ := chacha20.NewUnauthenticatedCipher(key, nonce)
|
||||||
var mac hash.Hash
|
|
||||||
subkey := make([]byte, 32)
|
subkey := make([]byte, 32)
|
||||||
hkdf := hkdf.New(sha3.New256, key, hkdfSalt, nil)
|
hkdf := hkdf.New(sha3.New256, key, hkdfSalt, nil)
|
||||||
hkdf.Read(subkey)
|
hkdf.Read(subkey)
|
||||||
if *paranoid {
|
if *p {
|
||||||
mac = hmac.New(sha3.New512, subkey)
|
mac = hmac.New(sha3.New512, subkey)
|
||||||
} else {
|
} else {
|
||||||
mac, _ = blake2b.New512(subkey)
|
mac, _ = blake2b.New512(subkey)
|
||||||
|
@ -467,7 +475,7 @@ func work() int {
|
||||||
)
|
)
|
||||||
for {
|
for {
|
||||||
var src []byte
|
var src []byte
|
||||||
if mode == "decrypt" && *reedsolo {
|
if mode == "decrypt" && *r {
|
||||||
src = make([]byte, MiB/128*136)
|
src = make([]byte, MiB/128*136)
|
||||||
} else {
|
} else {
|
||||||
src = make([]byte, MiB)
|
src = make([]byte, MiB)
|
||||||
|
@ -478,15 +486,16 @@ func work() int {
|
||||||
}
|
}
|
||||||
src = src[:size]
|
src = src[:size]
|
||||||
dst := make([]byte, len(src))
|
dst := make([]byte, len(src))
|
||||||
|
bar.Write(src)
|
||||||
|
|
||||||
if mode == "encrypt" {
|
if mode == "encrypt" {
|
||||||
if *paranoid {
|
if *p {
|
||||||
serpent.XORKeyStream(dst, src)
|
serpent.XORKeyStream(dst, src)
|
||||||
copy(src, dst)
|
copy(src, dst)
|
||||||
}
|
}
|
||||||
chacha.XORKeyStream(dst, src)
|
chacha.XORKeyStream(dst, src)
|
||||||
mac.Write(dst)
|
mac.Write(dst)
|
||||||
if *reedsolo {
|
if *r {
|
||||||
copy(src, dst)
|
copy(src, dst)
|
||||||
dst = nil
|
dst = nil
|
||||||
if len(src) == MiB {
|
if len(src) == MiB {
|
||||||
|
@ -502,16 +511,15 @@ func work() int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if *reedsolo {
|
if *r {
|
||||||
copy(dst, src)
|
copy(dst, src)
|
||||||
src = nil
|
src = nil
|
||||||
if len(dst) == MiB/128*136 {
|
if len(dst) == MiB/128*136 {
|
||||||
for i := 0; i < MiB/128*136; i += 136 {
|
for i := 0; i < MiB/128*136; i += 136 {
|
||||||
tmp, err := rsDecode(rs128, dst[i:i+136], !(*fix))
|
tmp, err := rsDecode(rs128, dst[i:i+136], !(*f))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
os.Remove(fout_)
|
|
||||||
fmt.Println("\nThe input file is irrecoverably damaged.")
|
fmt.Println("\nThe input file is irrecoverably damaged.")
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
@ -523,21 +531,19 @@ func work() int {
|
||||||
} else {
|
} else {
|
||||||
chunks := len(dst)/136 - 1
|
chunks := len(dst)/136 - 1
|
||||||
for i := 0; i < chunks; i++ {
|
for i := 0; i < chunks; i++ {
|
||||||
tmp, err := rsDecode(rs128, dst[i*136:(i+1)*136], !(*fix))
|
tmp, err := rsDecode(rs128, dst[i*136:(i+1)*136], !(*f))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
os.Remove(fout_)
|
|
||||||
fmt.Println("\nThe input file is irrecoverably damaged.")
|
fmt.Println("\nThe input file is irrecoverably damaged.")
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
src = append(src, tmp...)
|
src = append(src, tmp...)
|
||||||
}
|
}
|
||||||
tmp, err := rsDecode(rs128, dst[int(chunks)*136:], !(*fix))
|
tmp, err := rsDecode(rs128, dst[int(chunks)*136:], !(*f))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
os.Remove(fout_)
|
|
||||||
fmt.Println("\nThe input file is irrecoverably damaged.")
|
fmt.Println("\nThe input file is irrecoverably damaged.")
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
@ -547,7 +553,7 @@ func work() int {
|
||||||
}
|
}
|
||||||
mac.Write(src)
|
mac.Write(src)
|
||||||
chacha.XORKeyStream(dst, src)
|
chacha.XORKeyStream(dst, src)
|
||||||
if *paranoid {
|
if *p {
|
||||||
copy(src, dst)
|
copy(src, dst)
|
||||||
serpent.XORKeyStream(dst, src)
|
serpent.XORKeyStream(dst, src)
|
||||||
}
|
}
|
||||||
|
@ -555,19 +561,20 @@ func work() int {
|
||||||
|
|
||||||
_, err = fout.Write(dst)
|
_, err = fout.Write(dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fin.Close()
|
if interrupted {
|
||||||
fout.Close()
|
time.Sleep(1 * time.Second)
|
||||||
if err := os.Remove(fout.Name()); err == nil {
|
} else {
|
||||||
fmt.Print("\nSystem interrupt detected, cleaning up.")
|
fin.Close()
|
||||||
|
fout.Close()
|
||||||
|
fmt.Println("\nInsufficient disk space!")
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
return 1
|
|
||||||
}
|
}
|
||||||
if mode == "decrypt" && *reedsolo {
|
if mode == "decrypt" && *r {
|
||||||
done += MiB / 128 * 136
|
done += MiB / 128 * 136
|
||||||
} else {
|
} else {
|
||||||
done += MiB
|
done += MiB
|
||||||
}
|
}
|
||||||
bar.Set(done)
|
|
||||||
|
|
||||||
if counter >= 60*GiB {
|
if counter >= 60*GiB {
|
||||||
nonce = make([]byte, 24)
|
nonce = make([]byte, 24)
|
||||||
|
@ -579,39 +586,90 @@ func work() int {
|
||||||
counter = 0
|
counter = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bar.Set64(total)
|
|
||||||
|
|
||||||
if mode == "encrypt" {
|
if mode == "encrypt" {
|
||||||
fout.Seek(int64(309+0*3), 0)
|
fout.Seek(309, 0)
|
||||||
fout.Write(rsEncode(rs64, keyHash))
|
fout.Write(rsEncode(rs64, keyHash))
|
||||||
fout.Write(rsEncode(rs32, make([]byte, 32)))
|
fout.Write(rsEncode(rs32, make([]byte, 32)))
|
||||||
fout.Write(rsEncode(rs64, mac.Sum(nil)))
|
fout.Write(rsEncode(rs64, mac.Sum(nil)))
|
||||||
} else {
|
} else {
|
||||||
if subtle.ConstantTimeCompare(mac.Sum(nil), authTag) != 1 {
|
if !bytes.Equal(mac.Sum(nil), authTag) {
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
os.Remove(fout_)
|
if *k {
|
||||||
fmt.Println("\nThe input volume is damaged or modified.")
|
fmt.Println("\nThe modified output has been kept.")
|
||||||
if *reedsolo {
|
return 0
|
||||||
fmt.Println("Fortunately, this volume is encoded with Reed-Solomon.")
|
} else {
|
||||||
fmt.Println("Try again using the '-f' flag to repair the corruption.")
|
fmt.Println("\nThe input volume is damaged or modified!")
|
||||||
|
if *r {
|
||||||
|
fmt.Println("Fortunately, this volume is encoded with Reed-Solomon.")
|
||||||
|
fmt.Println("Try again using the '-f' flag to repair the corruption.")
|
||||||
|
}
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
return 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
fmt.Println("\nCompleted.")
|
fmt.Print("Completed -> ", fout.Name())
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
g, err := filepath.Glob(filepath.Join(os.TempDir(), "picocrypt-cli-v2-*.tmp"))
|
if parse() == 1 {
|
||||||
if err == nil {
|
os.Exit(1)
|
||||||
for _, v := range g {
|
}
|
||||||
os.Remove(v)
|
if auth() == 1 {
|
||||||
}
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if prepare() == 1 {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
c := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(c, os.Interrupt)
|
||||||
|
go func() {
|
||||||
|
<-c
|
||||||
|
interrupted = true
|
||||||
|
if fin != nil {
|
||||||
|
fin.Close()
|
||||||
|
}
|
||||||
|
if fout != nil {
|
||||||
|
fmt.Print("\nSystem interrupt detected, cleaning up incomplete output: ")
|
||||||
|
fout.Close()
|
||||||
|
if err := os.Remove(fout.Name()); err == nil {
|
||||||
|
fmt.Print("Success.")
|
||||||
|
} else {
|
||||||
|
fmt.Print("Failure.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pzip != "" {
|
||||||
|
fmt.Print("\nSystem interrupt detected, cleaning up temporary files: ")
|
||||||
|
writer.Close()
|
||||||
|
file.Close()
|
||||||
|
if err := os.Remove(pzip); err == nil {
|
||||||
|
fmt.Print("Success.")
|
||||||
|
} else {
|
||||||
|
fmt.Print("Failure.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
|
}()
|
||||||
|
|
||||||
|
if compress() == 1 {
|
||||||
|
os.Remove(pzip)
|
||||||
|
os.Exit(1)
|
||||||
|
} else {
|
||||||
|
defer os.Remove(pzip)
|
||||||
|
}
|
||||||
|
if work() == 1 {
|
||||||
|
if pzip != "" {
|
||||||
|
os.Remove(pzip)
|
||||||
|
}
|
||||||
|
if fout != nil {
|
||||||
|
os.Remove(fout.Name())
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
os.Exit(work())
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/////////////////
|
||||||
|
// Copyright notices
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
Copyright (C) 2016-2017 Vivint, Inc.
|
||||||
|
Copyright (c) 2015 Klaus Post
|
||||||
|
Copyright (c) 2015 Backblaze
|
||||||
|
Copyright (C) 2011 Billy Brumley (billy.brumley@aalto.fi)
|
||||||
|
Copyright (C) 2009-2010 Jack Lloyd (lloyd@randombit.net)
|
||||||
|
Copyright (C) 1996-1998 Luigi Rizzo (luigi@iet.unipi.it)
|
||||||
|
|
||||||
|
Portions derived from code by Phil Karn (karn@ka9q.ampr.org),
|
||||||
|
Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari
|
||||||
|
Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
// Portions of this project (labeled in each file) are licensed under this
|
||||||
|
// license:
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
// All other portions of this project are licensed under this license:
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
58
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/addmul_amd64.go
generated
vendored
Normal file
58
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/addmul_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2016-2017 Vivint, Inc.
|
||||||
|
// Copyright (c) 2015 Klaus Post
|
||||||
|
// Copyright (c) 2015 Backblaze
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package infectious
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func addmulSSSE3(lowhigh *pair, in, out *byte, n int, mul *byte)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func addmulAVX2(lowhigh *pair, in, out *byte, n int)
|
||||||
|
|
||||||
|
func addmul(z, x []byte, y byte) {
|
||||||
|
if len(z) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var done int
|
||||||
|
if hasAVX2 {
|
||||||
|
addmulAVX2(&mul_table_pair[y], &x[0], &z[0], len(z))
|
||||||
|
done = (len(x) >> 5) << 5
|
||||||
|
} else if hasSSSE3 {
|
||||||
|
addmulSSSE3(&mul_table_pair[y], &x[0], &z[0], len(z), &gf_mul_table[y][0])
|
||||||
|
//done = (len(x) >> 4) << 4
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if done < len(z) {
|
||||||
|
// hints to the compiler to remove bounds checks
|
||||||
|
z = z[done:]
|
||||||
|
x = x[done : done+len(z)]
|
||||||
|
|
||||||
|
gf_mul_y := gf_mul_table[y][:]
|
||||||
|
for i := range z {
|
||||||
|
z[i] ^= gf_mul_y[x[i]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
199
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/addmul_amd64.s
generated
vendored
Normal file
199
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/addmul_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2016-2017 Vivint, Inc.
|
||||||
|
// Copyright (c) 2015 Klaus Post
|
||||||
|
// Copyright (c) 2015 Backblaze
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
/*
|
||||||
|
The corresponding C implementations:
|
||||||
|
|
||||||
|
void addmul(
|
||||||
|
uint8_t * restrict lowhigh,
|
||||||
|
uint8_t * restrict in,
|
||||||
|
uint8_t * restrict out,
|
||||||
|
int n
|
||||||
|
) {
|
||||||
|
for(int i = 0; i < n; i++){
|
||||||
|
int value = in[i];
|
||||||
|
int low = value & 15;
|
||||||
|
int high = value >> 4;
|
||||||
|
out[i] = out[i] ^ lowhigh[low] ^ lowhigh[high+16];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addmulSSSE3(
|
||||||
|
uint8_t * restrict lowhigh,
|
||||||
|
uint8_t * restrict in,
|
||||||
|
uint8_t * restrict out,
|
||||||
|
int n
|
||||||
|
) {
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
__m128i lotbl = _mm_loadu_si128((__m128i*)(&lowhigh[0]));
|
||||||
|
__m128i hitbl = _mm_loadu_si128((__m128i*)(&lowhigh[16]));
|
||||||
|
|
||||||
|
__m128i lomask = _mm_set1_epi8(0xF);
|
||||||
|
|
||||||
|
#pragma nounroll
|
||||||
|
for(i = 0; i < (n/16)*16; i += 16){
|
||||||
|
__m128i input8 = _mm_loadu_si128((__m128i*)(&in[i]));
|
||||||
|
__m128i output8 = _mm_loadu_si128((__m128i*)(&out[i]));
|
||||||
|
|
||||||
|
__m128i lo8 = _mm_and_si128(lomask, input8);
|
||||||
|
__m128i hi8 = _mm_and_si128(lomask, _mm_srli_si128(input8, 4)); // simulate shrli epi8
|
||||||
|
|
||||||
|
output8 = _mm_xor_si128(output8, _mm_shuffle_epi8(lotbl, lo8));
|
||||||
|
output8 = _mm_xor_si128(output8, _mm_shuffle_epi8(hitbl, hi8));
|
||||||
|
|
||||||
|
_mm_storeu_si128((__m128i*)(&out[i]), output8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
DATA nybble_mask<>+0x00(SB)/8, $0x0F0F0F0F0F0F0F0F
|
||||||
|
DATA nybble_mask<>+0x08(SB)/8, $0x0F0F0F0F0F0F0F0F
|
||||||
|
DATA nybble_mask<>+0x10(SB)/8, $0x0F0F0F0F0F0F0F0F
|
||||||
|
DATA nybble_mask<>+0x18(SB)/8, $0x0F0F0F0F0F0F0F0F
|
||||||
|
GLOBL nybble_mask<>(SB), (NOPTR+RODATA), $32
|
||||||
|
|
||||||
|
#define LOWHIGH DI
|
||||||
|
#define LOW X8
|
||||||
|
#define HIGH X9
|
||||||
|
#define IN SI
|
||||||
|
#define OUT DX
|
||||||
|
#define INDEX AX
|
||||||
|
|
||||||
|
#define LEN CX
|
||||||
|
#define LEN16 R8 // LEN16 = (LEN / 16) * 16
|
||||||
|
|
||||||
|
#define LOMASK X7 // LOMASK = repeated 15
|
||||||
|
// X0-X5 temps
|
||||||
|
|
||||||
|
// func addmulSSSE3(lowhigh *[2][16]byte, in, out *byte, len int)
|
||||||
|
TEXT ·addmulSSSE3(SB), 7, $0
|
||||||
|
MOVQ _in+8(FP), IN
|
||||||
|
MOVQ _out+16(FP), OUT
|
||||||
|
MOVQ _len+24(FP), LEN
|
||||||
|
|
||||||
|
MOVQ LEN, LEN16
|
||||||
|
ANDQ $-16, LEN16
|
||||||
|
|
||||||
|
JLE start_slow // if LEN16 == 0 { goto done }
|
||||||
|
|
||||||
|
MOVQ _lohi+0(FP), LOWHIGH
|
||||||
|
MOVOU (LOWHIGH), LOW
|
||||||
|
MOVOU 16(LOWHIGH), HIGH
|
||||||
|
|
||||||
|
MOVOU nybble_mask<>(SB), LOMASK
|
||||||
|
XORQ INDEX, INDEX // INDEX = 0
|
||||||
|
|
||||||
|
loop16:
|
||||||
|
MOVOU (IN)(INDEX*1), X0 // X0 = INPUT[INDEX]
|
||||||
|
MOVOU LOW, X4 // X4 = copy(LOW)
|
||||||
|
MOVOU (OUT)(INDEX*1), X2 // X2 = OUT[INDEX]
|
||||||
|
MOVOU X0, X1 // X0 = input[index] & 15
|
||||||
|
MOVOU HIGH, X5 // X5 = copy(HIGH)
|
||||||
|
|
||||||
|
PAND LOMASK, X0
|
||||||
|
PSRLQ $4, X1 // X1 = input[index]
|
||||||
|
PSHUFB X0, X4 // X4 = LOW[X0]
|
||||||
|
|
||||||
|
PAND LOMASK, X1 // X1 = input[index] >> 4
|
||||||
|
PSHUFB X1, X5 // X5 = HIGH[X1]
|
||||||
|
PXOR X4, X2 // X2 = OUT[INDEX] ^ X4 ^ X5
|
||||||
|
PXOR X5, X2
|
||||||
|
|
||||||
|
MOVOU X2, 0(OUT)(INDEX*1)
|
||||||
|
|
||||||
|
ADDQ $16, INDEX
|
||||||
|
CMPQ LEN16, INDEX // INDEX < LEN16
|
||||||
|
JG loop16
|
||||||
|
|
||||||
|
start_slow:
|
||||||
|
MOVQ _len+32(FP), LOWHIGH
|
||||||
|
MOVQ LEN16, INDEX
|
||||||
|
CMPQ LEN, INDEX
|
||||||
|
JLE done
|
||||||
|
|
||||||
|
loop1:
|
||||||
|
MOVBQZX (IN)(INDEX*1), R9 // R9 := in[index]
|
||||||
|
MOVBQZX (LOWHIGH)(R9*1), R10 // R10 := multiply[R9]
|
||||||
|
XORB R10B, (OUT)(INDEX*1) // out[index] ^= R10
|
||||||
|
INCQ INDEX
|
||||||
|
CMPQ LEN, INDEX
|
||||||
|
JG loop1
|
||||||
|
|
||||||
|
done:
|
||||||
|
RET
|
||||||
|
|
||||||
|
#undef LOWHIGH
|
||||||
|
#undef LOW
|
||||||
|
#undef HIGH
|
||||||
|
#undef IN
|
||||||
|
#undef OUT
|
||||||
|
#undef LEN
|
||||||
|
#undef INDEX
|
||||||
|
#undef LEN16
|
||||||
|
#undef LOMASK
|
||||||
|
|
||||||
|
// func addmulAVX2(lowhigh *[2][16]byte, in, out *byte, len int)
|
||||||
|
TEXT ·addmulAVX2(SB), 7, $0
|
||||||
|
MOVQ low+0(FP), SI // SI: &lowhigh
|
||||||
|
MOVOU (SI), X6 // X6: low
|
||||||
|
MOVOU 16(SI), X7 // X7: high
|
||||||
|
|
||||||
|
MOVQ $15, BX // BX: low mask
|
||||||
|
MOVQ BX, X5
|
||||||
|
|
||||||
|
MOVQ len+24(FP), R9 // R9: len(in), len(out)
|
||||||
|
|
||||||
|
LONG $0x384de3c4; WORD $0x01f6 // VINSERTI128 YMM6, YMM6, XMM6, 1 ; low
|
||||||
|
LONG $0x3845e3c4; WORD $0x01ff // VINSERTI128 YMM7, YMM7, XMM7, 1 ; high
|
||||||
|
LONG $0x787d62c4; BYTE $0xc5 // VPBROADCASTB YMM8, XMM5 ; X8: lomask (unpacked)
|
||||||
|
|
||||||
|
SHRQ $5, R9 // len(in) / 32
|
||||||
|
MOVQ out+16(FP), DX // DX: &out
|
||||||
|
MOVQ in+8(FP), SI // R11: &in
|
||||||
|
TESTQ R9, R9
|
||||||
|
JZ done_xor_avx2
|
||||||
|
|
||||||
|
loopback_xor_avx2:
|
||||||
|
LONG $0x066ffec5 // VMOVDQU YMM0, [rsi]
|
||||||
|
LONG $0x226ffec5 // VMOVDQU YMM4, [rdx]
|
||||||
|
LONG $0xd073f5c5; BYTE $0x04 // VPSRLQ YMM1, YMM0, 4 ; X1: high input
|
||||||
|
LONG $0xdb7dc1c4; BYTE $0xc0 // VPAND YMM0, YMM0, YMM8 ; X0: low input
|
||||||
|
LONG $0xdb75c1c4; BYTE $0xc8 // VPAND YMM1, YMM1, YMM8 ; X1: high input
|
||||||
|
LONG $0x004de2c4; BYTE $0xd0 // VPSHUFB YMM2, YMM6, YMM0 ; X2: mul low part
|
||||||
|
LONG $0x0045e2c4; BYTE $0xd9 // VPSHUFB YMM3, YMM7, YMM1 ; X2: mul high part
|
||||||
|
LONG $0xdbefedc5 // VPXOR YMM3, YMM2, YMM3 ; X3: Result
|
||||||
|
LONG $0xe4efe5c5 // VPXOR YMM4, YMM3, YMM4 ; X4: Result
|
||||||
|
LONG $0x227ffec5 // VMOVDQU [rdx], YMM4
|
||||||
|
|
||||||
|
ADDQ $32, SI // in+=32
|
||||||
|
ADDQ $32, DX // out+=32
|
||||||
|
SUBQ $1, R9
|
||||||
|
JNZ loopback_xor_avx2
|
||||||
|
|
||||||
|
done_xor_avx2:
|
||||||
|
// VZEROUPPER
|
||||||
|
BYTE $0xc5; BYTE $0xf8; BYTE $0x77
|
||||||
|
RET
|
40
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/addmul_noasm.go
generated
vendored
Normal file
40
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/addmul_noasm.go
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2016-2017 Vivint, Inc.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
//go:build !amd64
|
||||||
|
|
||||||
|
package infectious
|
||||||
|
|
||||||
|
func addmul(z []byte, x []byte, y byte) {
|
||||||
|
if y == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// hint to the compiler that we don't need bounds checks on x
|
||||||
|
x = x[:len(z)]
|
||||||
|
|
||||||
|
// TODO(jeff): loop unrolling for SPEEDS
|
||||||
|
gf_mul_y := gf_mul_table[y][:]
|
||||||
|
for i := range z {
|
||||||
|
z[i] ^= gf_mul_y[x[i]]
|
||||||
|
}
|
||||||
|
}
|
288
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/addmul_tables_amd64.go
generated
vendored
Normal file
288
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/addmul_tables_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2016-2017 Vivint, Inc.
|
||||||
|
// Copyright (c) 2015 Klaus Post
|
||||||
|
// Copyright (c) 2015 Backblaze
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package infectious
|
||||||
|
|
||||||
|
type pair struct {
|
||||||
|
low, high [16]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
var mul_table_pair = [256]pair{
|
||||||
|
{[16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, [16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||||
|
{[16]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, [16]byte{0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0}},
|
||||||
|
{[16]byte{0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e}, [16]byte{0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x1d, 0x3d, 0x5d, 0x7d, 0x9d, 0xbd, 0xdd, 0xfd}},
|
||||||
|
{[16]byte{0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11}, [16]byte{0x00, 0x30, 0x60, 0x50, 0xc0, 0xf0, 0xa0, 0x90, 0x9d, 0xad, 0xfd, 0xcd, 0x5d, 0x6d, 0x3d, 0x0d}},
|
||||||
|
{[16]byte{0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c}, [16]byte{0x00, 0x40, 0x80, 0xc0, 0x1d, 0x5d, 0x9d, 0xdd, 0x3a, 0x7a, 0xba, 0xfa, 0x27, 0x67, 0xa7, 0xe7}},
|
||||||
|
{[16]byte{0x00, 0x05, 0x0a, 0x0f, 0x14, 0x11, 0x1e, 0x1b, 0x28, 0x2d, 0x22, 0x27, 0x3c, 0x39, 0x36, 0x33}, [16]byte{0x00, 0x50, 0xa0, 0xf0, 0x5d, 0x0d, 0xfd, 0xad, 0xba, 0xea, 0x1a, 0x4a, 0xe7, 0xb7, 0x47, 0x17}},
|
||||||
|
{[16]byte{0x00, 0x06, 0x0c, 0x0a, 0x18, 0x1e, 0x14, 0x12, 0x30, 0x36, 0x3c, 0x3a, 0x28, 0x2e, 0x24, 0x22}, [16]byte{0x00, 0x60, 0xc0, 0xa0, 0x9d, 0xfd, 0x5d, 0x3d, 0x27, 0x47, 0xe7, 0x87, 0xba, 0xda, 0x7a, 0x1a}},
|
||||||
|
{[16]byte{0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d}, [16]byte{0x00, 0x70, 0xe0, 0x90, 0xdd, 0xad, 0x3d, 0x4d, 0xa7, 0xd7, 0x47, 0x37, 0x7a, 0x0a, 0x9a, 0xea}},
|
||||||
|
{[16]byte{0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78}, [16]byte{0x00, 0x80, 0x1d, 0x9d, 0x3a, 0xba, 0x27, 0xa7, 0x74, 0xf4, 0x69, 0xe9, 0x4e, 0xce, 0x53, 0xd3}},
|
||||||
|
{[16]byte{0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77}, [16]byte{0x00, 0x90, 0x3d, 0xad, 0x7a, 0xea, 0x47, 0xd7, 0xf4, 0x64, 0xc9, 0x59, 0x8e, 0x1e, 0xb3, 0x23}},
|
||||||
|
{[16]byte{0x00, 0x0a, 0x14, 0x1e, 0x28, 0x22, 0x3c, 0x36, 0x50, 0x5a, 0x44, 0x4e, 0x78, 0x72, 0x6c, 0x66}, [16]byte{0x00, 0xa0, 0x5d, 0xfd, 0xba, 0x1a, 0xe7, 0x47, 0x69, 0xc9, 0x34, 0x94, 0xd3, 0x73, 0x8e, 0x2e}},
|
||||||
|
{[16]byte{0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69}, [16]byte{0x00, 0xb0, 0x7d, 0xcd, 0xfa, 0x4a, 0x87, 0x37, 0xe9, 0x59, 0x94, 0x24, 0x13, 0xa3, 0x6e, 0xde}},
|
||||||
|
{[16]byte{0x00, 0x0c, 0x18, 0x14, 0x30, 0x3c, 0x28, 0x24, 0x60, 0x6c, 0x78, 0x74, 0x50, 0x5c, 0x48, 0x44}, [16]byte{0x00, 0xc0, 0x9d, 0x5d, 0x27, 0xe7, 0xba, 0x7a, 0x4e, 0x8e, 0xd3, 0x13, 0x69, 0xa9, 0xf4, 0x34}},
|
||||||
|
{[16]byte{0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b}, [16]byte{0x00, 0xd0, 0xbd, 0x6d, 0x67, 0xb7, 0xda, 0x0a, 0xce, 0x1e, 0x73, 0xa3, 0xa9, 0x79, 0x14, 0xc4}},
|
||||||
|
{[16]byte{0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a}, [16]byte{0x00, 0xe0, 0xdd, 0x3d, 0xa7, 0x47, 0x7a, 0x9a, 0x53, 0xb3, 0x8e, 0x6e, 0xf4, 0x14, 0x29, 0xc9}},
|
||||||
|
{[16]byte{0x00, 0x0f, 0x1e, 0x11, 0x3c, 0x33, 0x22, 0x2d, 0x78, 0x77, 0x66, 0x69, 0x44, 0x4b, 0x5a, 0x55}, [16]byte{0x00, 0xf0, 0xfd, 0x0d, 0xe7, 0x17, 0x1a, 0xea, 0xd3, 0x23, 0x2e, 0xde, 0x34, 0xc4, 0xc9, 0x39}},
|
||||||
|
{[16]byte{0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0}, [16]byte{0x00, 0x1d, 0x3a, 0x27, 0x74, 0x69, 0x4e, 0x53, 0xe8, 0xf5, 0xd2, 0xcf, 0x9c, 0x81, 0xa6, 0xbb}},
|
||||||
|
{[16]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, [16]byte{0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b}},
|
||||||
|
{[16]byte{0x00, 0x12, 0x24, 0x36, 0x48, 0x5a, 0x6c, 0x7e, 0x90, 0x82, 0xb4, 0xa6, 0xd8, 0xca, 0xfc, 0xee}, [16]byte{0x00, 0x3d, 0x7a, 0x47, 0xf4, 0xc9, 0x8e, 0xb3, 0xf5, 0xc8, 0x8f, 0xb2, 0x01, 0x3c, 0x7b, 0x46}},
|
||||||
|
{[16]byte{0x00, 0x13, 0x26, 0x35, 0x4c, 0x5f, 0x6a, 0x79, 0x98, 0x8b, 0xbe, 0xad, 0xd4, 0xc7, 0xf2, 0xe1}, [16]byte{0x00, 0x2d, 0x5a, 0x77, 0xb4, 0x99, 0xee, 0xc3, 0x75, 0x58, 0x2f, 0x02, 0xc1, 0xec, 0x9b, 0xb6}},
|
||||||
|
{[16]byte{0x00, 0x14, 0x28, 0x3c, 0x50, 0x44, 0x78, 0x6c, 0xa0, 0xb4, 0x88, 0x9c, 0xf0, 0xe4, 0xd8, 0xcc}, [16]byte{0x00, 0x5d, 0xba, 0xe7, 0x69, 0x34, 0xd3, 0x8e, 0xd2, 0x8f, 0x68, 0x35, 0xbb, 0xe6, 0x01, 0x5c}},
|
||||||
|
{[16]byte{0x00, 0x15, 0x2a, 0x3f, 0x54, 0x41, 0x7e, 0x6b, 0xa8, 0xbd, 0x82, 0x97, 0xfc, 0xe9, 0xd6, 0xc3}, [16]byte{0x00, 0x4d, 0x9a, 0xd7, 0x29, 0x64, 0xb3, 0xfe, 0x52, 0x1f, 0xc8, 0x85, 0x7b, 0x36, 0xe1, 0xac}},
|
||||||
|
{[16]byte{0x00, 0x16, 0x2c, 0x3a, 0x58, 0x4e, 0x74, 0x62, 0xb0, 0xa6, 0x9c, 0x8a, 0xe8, 0xfe, 0xc4, 0xd2}, [16]byte{0x00, 0x7d, 0xfa, 0x87, 0xe9, 0x94, 0x13, 0x6e, 0xcf, 0xb2, 0x35, 0x48, 0x26, 0x5b, 0xdc, 0xa1}},
|
||||||
|
{[16]byte{0x00, 0x17, 0x2e, 0x39, 0x5c, 0x4b, 0x72, 0x65, 0xb8, 0xaf, 0x96, 0x81, 0xe4, 0xf3, 0xca, 0xdd}, [16]byte{0x00, 0x6d, 0xda, 0xb7, 0xa9, 0xc4, 0x73, 0x1e, 0x4f, 0x22, 0x95, 0xf8, 0xe6, 0x8b, 0x3c, 0x51}},
|
||||||
|
{[16]byte{0x00, 0x18, 0x30, 0x28, 0x60, 0x78, 0x50, 0x48, 0xc0, 0xd8, 0xf0, 0xe8, 0xa0, 0xb8, 0x90, 0x88}, [16]byte{0x00, 0x9d, 0x27, 0xba, 0x4e, 0xd3, 0x69, 0xf4, 0x9c, 0x01, 0xbb, 0x26, 0xd2, 0x4f, 0xf5, 0x68}},
|
||||||
|
{[16]byte{0x00, 0x19, 0x32, 0x2b, 0x64, 0x7d, 0x56, 0x4f, 0xc8, 0xd1, 0xfa, 0xe3, 0xac, 0xb5, 0x9e, 0x87}, [16]byte{0x00, 0x8d, 0x07, 0x8a, 0x0e, 0x83, 0x09, 0x84, 0x1c, 0x91, 0x1b, 0x96, 0x12, 0x9f, 0x15, 0x98}},
|
||||||
|
{[16]byte{0x00, 0x1a, 0x34, 0x2e, 0x68, 0x72, 0x5c, 0x46, 0xd0, 0xca, 0xe4, 0xfe, 0xb8, 0xa2, 0x8c, 0x96}, [16]byte{0x00, 0xbd, 0x67, 0xda, 0xce, 0x73, 0xa9, 0x14, 0x81, 0x3c, 0xe6, 0x5b, 0x4f, 0xf2, 0x28, 0x95}},
|
||||||
|
{[16]byte{0x00, 0x1b, 0x36, 0x2d, 0x6c, 0x77, 0x5a, 0x41, 0xd8, 0xc3, 0xee, 0xf5, 0xb4, 0xaf, 0x82, 0x99}, [16]byte{0x00, 0xad, 0x47, 0xea, 0x8e, 0x23, 0xc9, 0x64, 0x01, 0xac, 0x46, 0xeb, 0x8f, 0x22, 0xc8, 0x65}},
|
||||||
|
{[16]byte{0x00, 0x1c, 0x38, 0x24, 0x70, 0x6c, 0x48, 0x54, 0xe0, 0xfc, 0xd8, 0xc4, 0x90, 0x8c, 0xa8, 0xb4}, [16]byte{0x00, 0xdd, 0xa7, 0x7a, 0x53, 0x8e, 0xf4, 0x29, 0xa6, 0x7b, 0x01, 0xdc, 0xf5, 0x28, 0x52, 0x8f}},
|
||||||
|
{[16]byte{0x00, 0x1d, 0x3a, 0x27, 0x74, 0x69, 0x4e, 0x53, 0xe8, 0xf5, 0xd2, 0xcf, 0x9c, 0x81, 0xa6, 0xbb}, [16]byte{0x00, 0xcd, 0x87, 0x4a, 0x13, 0xde, 0x94, 0x59, 0x26, 0xeb, 0xa1, 0x6c, 0x35, 0xf8, 0xb2, 0x7f}},
|
||||||
|
{[16]byte{0x00, 0x1e, 0x3c, 0x22, 0x78, 0x66, 0x44, 0x5a, 0xf0, 0xee, 0xcc, 0xd2, 0x88, 0x96, 0xb4, 0xaa}, [16]byte{0x00, 0xfd, 0xe7, 0x1a, 0xd3, 0x2e, 0x34, 0xc9, 0xbb, 0x46, 0x5c, 0xa1, 0x68, 0x95, 0x8f, 0x72}},
|
||||||
|
{[16]byte{0x00, 0x1f, 0x3e, 0x21, 0x7c, 0x63, 0x42, 0x5d, 0xf8, 0xe7, 0xc6, 0xd9, 0x84, 0x9b, 0xba, 0xa5}, [16]byte{0x00, 0xed, 0xc7, 0x2a, 0x93, 0x7e, 0x54, 0xb9, 0x3b, 0xd6, 0xfc, 0x11, 0xa8, 0x45, 0x6f, 0x82}},
|
||||||
|
{[16]byte{0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x1d, 0x3d, 0x5d, 0x7d, 0x9d, 0xbd, 0xdd, 0xfd}, [16]byte{0x00, 0x3a, 0x74, 0x4e, 0xe8, 0xd2, 0x9c, 0xa6, 0xcd, 0xf7, 0xb9, 0x83, 0x25, 0x1f, 0x51, 0x6b}},
|
||||||
|
{[16]byte{0x00, 0x21, 0x42, 0x63, 0x84, 0xa5, 0xc6, 0xe7, 0x15, 0x34, 0x57, 0x76, 0x91, 0xb0, 0xd3, 0xf2}, [16]byte{0x00, 0x2a, 0x54, 0x7e, 0xa8, 0x82, 0xfc, 0xd6, 0x4d, 0x67, 0x19, 0x33, 0xe5, 0xcf, 0xb1, 0x9b}},
|
||||||
|
{[16]byte{0x00, 0x22, 0x44, 0x66, 0x88, 0xaa, 0xcc, 0xee, 0x0d, 0x2f, 0x49, 0x6b, 0x85, 0xa7, 0xc1, 0xe3}, [16]byte{0x00, 0x1a, 0x34, 0x2e, 0x68, 0x72, 0x5c, 0x46, 0xd0, 0xca, 0xe4, 0xfe, 0xb8, 0xa2, 0x8c, 0x96}},
|
||||||
|
{[16]byte{0x00, 0x23, 0x46, 0x65, 0x8c, 0xaf, 0xca, 0xe9, 0x05, 0x26, 0x43, 0x60, 0x89, 0xaa, 0xcf, 0xec}, [16]byte{0x00, 0x0a, 0x14, 0x1e, 0x28, 0x22, 0x3c, 0x36, 0x50, 0x5a, 0x44, 0x4e, 0x78, 0x72, 0x6c, 0x66}},
|
||||||
|
{[16]byte{0x00, 0x24, 0x48, 0x6c, 0x90, 0xb4, 0xd8, 0xfc, 0x3d, 0x19, 0x75, 0x51, 0xad, 0x89, 0xe5, 0xc1}, [16]byte{0x00, 0x7a, 0xf4, 0x8e, 0xf5, 0x8f, 0x01, 0x7b, 0xf7, 0x8d, 0x03, 0x79, 0x02, 0x78, 0xf6, 0x8c}},
|
||||||
|
{[16]byte{0x00, 0x25, 0x4a, 0x6f, 0x94, 0xb1, 0xde, 0xfb, 0x35, 0x10, 0x7f, 0x5a, 0xa1, 0x84, 0xeb, 0xce}, [16]byte{0x00, 0x6a, 0xd4, 0xbe, 0xb5, 0xdf, 0x61, 0x0b, 0x77, 0x1d, 0xa3, 0xc9, 0xc2, 0xa8, 0x16, 0x7c}},
|
||||||
|
{[16]byte{0x00, 0x26, 0x4c, 0x6a, 0x98, 0xbe, 0xd4, 0xf2, 0x2d, 0x0b, 0x61, 0x47, 0xb5, 0x93, 0xf9, 0xdf}, [16]byte{0x00, 0x5a, 0xb4, 0xee, 0x75, 0x2f, 0xc1, 0x9b, 0xea, 0xb0, 0x5e, 0x04, 0x9f, 0xc5, 0x2b, 0x71}},
|
||||||
|
{[16]byte{0x00, 0x27, 0x4e, 0x69, 0x9c, 0xbb, 0xd2, 0xf5, 0x25, 0x02, 0x6b, 0x4c, 0xb9, 0x9e, 0xf7, 0xd0}, [16]byte{0x00, 0x4a, 0x94, 0xde, 0x35, 0x7f, 0xa1, 0xeb, 0x6a, 0x20, 0xfe, 0xb4, 0x5f, 0x15, 0xcb, 0x81}},
|
||||||
|
{[16]byte{0x00, 0x28, 0x50, 0x78, 0xa0, 0x88, 0xf0, 0xd8, 0x5d, 0x75, 0x0d, 0x25, 0xfd, 0xd5, 0xad, 0x85}, [16]byte{0x00, 0xba, 0x69, 0xd3, 0xd2, 0x68, 0xbb, 0x01, 0xb9, 0x03, 0xd0, 0x6a, 0x6b, 0xd1, 0x02, 0xb8}},
|
||||||
|
{[16]byte{0x00, 0x29, 0x52, 0x7b, 0xa4, 0x8d, 0xf6, 0xdf, 0x55, 0x7c, 0x07, 0x2e, 0xf1, 0xd8, 0xa3, 0x8a}, [16]byte{0x00, 0xaa, 0x49, 0xe3, 0x92, 0x38, 0xdb, 0x71, 0x39, 0x93, 0x70, 0xda, 0xab, 0x01, 0xe2, 0x48}},
|
||||||
|
{[16]byte{0x00, 0x2a, 0x54, 0x7e, 0xa8, 0x82, 0xfc, 0xd6, 0x4d, 0x67, 0x19, 0x33, 0xe5, 0xcf, 0xb1, 0x9b}, [16]byte{0x00, 0x9a, 0x29, 0xb3, 0x52, 0xc8, 0x7b, 0xe1, 0xa4, 0x3e, 0x8d, 0x17, 0xf6, 0x6c, 0xdf, 0x45}},
|
||||||
|
{[16]byte{0x00, 0x2b, 0x56, 0x7d, 0xac, 0x87, 0xfa, 0xd1, 0x45, 0x6e, 0x13, 0x38, 0xe9, 0xc2, 0xbf, 0x94}, [16]byte{0x00, 0x8a, 0x09, 0x83, 0x12, 0x98, 0x1b, 0x91, 0x24, 0xae, 0x2d, 0xa7, 0x36, 0xbc, 0x3f, 0xb5}},
|
||||||
|
{[16]byte{0x00, 0x2c, 0x58, 0x74, 0xb0, 0x9c, 0xe8, 0xc4, 0x7d, 0x51, 0x25, 0x09, 0xcd, 0xe1, 0x95, 0xb9}, [16]byte{0x00, 0xfa, 0xe9, 0x13, 0xcf, 0x35, 0x26, 0xdc, 0x83, 0x79, 0x6a, 0x90, 0x4c, 0xb6, 0xa5, 0x5f}},
|
||||||
|
{[16]byte{0x00, 0x2d, 0x5a, 0x77, 0xb4, 0x99, 0xee, 0xc3, 0x75, 0x58, 0x2f, 0x02, 0xc1, 0xec, 0x9b, 0xb6}, [16]byte{0x00, 0xea, 0xc9, 0x23, 0x8f, 0x65, 0x46, 0xac, 0x03, 0xe9, 0xca, 0x20, 0x8c, 0x66, 0x45, 0xaf}},
|
||||||
|
{[16]byte{0x00, 0x2e, 0x5c, 0x72, 0xb8, 0x96, 0xe4, 0xca, 0x6d, 0x43, 0x31, 0x1f, 0xd5, 0xfb, 0x89, 0xa7}, [16]byte{0x00, 0xda, 0xa9, 0x73, 0x4f, 0x95, 0xe6, 0x3c, 0x9e, 0x44, 0x37, 0xed, 0xd1, 0x0b, 0x78, 0xa2}},
|
||||||
|
{[16]byte{0x00, 0x2f, 0x5e, 0x71, 0xbc, 0x93, 0xe2, 0xcd, 0x65, 0x4a, 0x3b, 0x14, 0xd9, 0xf6, 0x87, 0xa8}, [16]byte{0x00, 0xca, 0x89, 0x43, 0x0f, 0xc5, 0x86, 0x4c, 0x1e, 0xd4, 0x97, 0x5d, 0x11, 0xdb, 0x98, 0x52}},
|
||||||
|
{[16]byte{0x00, 0x30, 0x60, 0x50, 0xc0, 0xf0, 0xa0, 0x90, 0x9d, 0xad, 0xfd, 0xcd, 0x5d, 0x6d, 0x3d, 0x0d}, [16]byte{0x00, 0x27, 0x4e, 0x69, 0x9c, 0xbb, 0xd2, 0xf5, 0x25, 0x02, 0x6b, 0x4c, 0xb9, 0x9e, 0xf7, 0xd0}},
|
||||||
|
{[16]byte{0x00, 0x31, 0x62, 0x53, 0xc4, 0xf5, 0xa6, 0x97, 0x95, 0xa4, 0xf7, 0xc6, 0x51, 0x60, 0x33, 0x02}, [16]byte{0x00, 0x37, 0x6e, 0x59, 0xdc, 0xeb, 0xb2, 0x85, 0xa5, 0x92, 0xcb, 0xfc, 0x79, 0x4e, 0x17, 0x20}},
|
||||||
|
{[16]byte{0x00, 0x32, 0x64, 0x56, 0xc8, 0xfa, 0xac, 0x9e, 0x8d, 0xbf, 0xe9, 0xdb, 0x45, 0x77, 0x21, 0x13}, [16]byte{0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d}},
|
||||||
|
{[16]byte{0x00, 0x33, 0x66, 0x55, 0xcc, 0xff, 0xaa, 0x99, 0x85, 0xb6, 0xe3, 0xd0, 0x49, 0x7a, 0x2f, 0x1c}, [16]byte{0x00, 0x17, 0x2e, 0x39, 0x5c, 0x4b, 0x72, 0x65, 0xb8, 0xaf, 0x96, 0x81, 0xe4, 0xf3, 0xca, 0xdd}},
|
||||||
|
{[16]byte{0x00, 0x34, 0x68, 0x5c, 0xd0, 0xe4, 0xb8, 0x8c, 0xbd, 0x89, 0xd5, 0xe1, 0x6d, 0x59, 0x05, 0x31}, [16]byte{0x00, 0x67, 0xce, 0xa9, 0x81, 0xe6, 0x4f, 0x28, 0x1f, 0x78, 0xd1, 0xb6, 0x9e, 0xf9, 0x50, 0x37}},
|
||||||
|
{[16]byte{0x00, 0x35, 0x6a, 0x5f, 0xd4, 0xe1, 0xbe, 0x8b, 0xb5, 0x80, 0xdf, 0xea, 0x61, 0x54, 0x0b, 0x3e}, [16]byte{0x00, 0x77, 0xee, 0x99, 0xc1, 0xb6, 0x2f, 0x58, 0x9f, 0xe8, 0x71, 0x06, 0x5e, 0x29, 0xb0, 0xc7}},
|
||||||
|
{[16]byte{0x00, 0x36, 0x6c, 0x5a, 0xd8, 0xee, 0xb4, 0x82, 0xad, 0x9b, 0xc1, 0xf7, 0x75, 0x43, 0x19, 0x2f}, [16]byte{0x00, 0x47, 0x8e, 0xc9, 0x01, 0x46, 0x8f, 0xc8, 0x02, 0x45, 0x8c, 0xcb, 0x03, 0x44, 0x8d, 0xca}},
|
||||||
|
{[16]byte{0x00, 0x37, 0x6e, 0x59, 0xdc, 0xeb, 0xb2, 0x85, 0xa5, 0x92, 0xcb, 0xfc, 0x79, 0x4e, 0x17, 0x20}, [16]byte{0x00, 0x57, 0xae, 0xf9, 0x41, 0x16, 0xef, 0xb8, 0x82, 0xd5, 0x2c, 0x7b, 0xc3, 0x94, 0x6d, 0x3a}},
|
||||||
|
{[16]byte{0x00, 0x38, 0x70, 0x48, 0xe0, 0xd8, 0x90, 0xa8, 0xdd, 0xe5, 0xad, 0x95, 0x3d, 0x05, 0x4d, 0x75}, [16]byte{0x00, 0xa7, 0x53, 0xf4, 0xa6, 0x01, 0xf5, 0x52, 0x51, 0xf6, 0x02, 0xa5, 0xf7, 0x50, 0xa4, 0x03}},
|
||||||
|
{[16]byte{0x00, 0x39, 0x72, 0x4b, 0xe4, 0xdd, 0x96, 0xaf, 0xd5, 0xec, 0xa7, 0x9e, 0x31, 0x08, 0x43, 0x7a}, [16]byte{0x00, 0xb7, 0x73, 0xc4, 0xe6, 0x51, 0x95, 0x22, 0xd1, 0x66, 0xa2, 0x15, 0x37, 0x80, 0x44, 0xf3}},
|
||||||
|
{[16]byte{0x00, 0x3a, 0x74, 0x4e, 0xe8, 0xd2, 0x9c, 0xa6, 0xcd, 0xf7, 0xb9, 0x83, 0x25, 0x1f, 0x51, 0x6b}, [16]byte{0x00, 0x87, 0x13, 0x94, 0x26, 0xa1, 0x35, 0xb2, 0x4c, 0xcb, 0x5f, 0xd8, 0x6a, 0xed, 0x79, 0xfe}},
|
||||||
|
{[16]byte{0x00, 0x3b, 0x76, 0x4d, 0xec, 0xd7, 0x9a, 0xa1, 0xc5, 0xfe, 0xb3, 0x88, 0x29, 0x12, 0x5f, 0x64}, [16]byte{0x00, 0x97, 0x33, 0xa4, 0x66, 0xf1, 0x55, 0xc2, 0xcc, 0x5b, 0xff, 0x68, 0xaa, 0x3d, 0x99, 0x0e}},
|
||||||
|
{[16]byte{0x00, 0x3c, 0x78, 0x44, 0xf0, 0xcc, 0x88, 0xb4, 0xfd, 0xc1, 0x85, 0xb9, 0x0d, 0x31, 0x75, 0x49}, [16]byte{0x00, 0xe7, 0xd3, 0x34, 0xbb, 0x5c, 0x68, 0x8f, 0x6b, 0x8c, 0xb8, 0x5f, 0xd0, 0x37, 0x03, 0xe4}},
|
||||||
|
{[16]byte{0x00, 0x3d, 0x7a, 0x47, 0xf4, 0xc9, 0x8e, 0xb3, 0xf5, 0xc8, 0x8f, 0xb2, 0x01, 0x3c, 0x7b, 0x46}, [16]byte{0x00, 0xf7, 0xf3, 0x04, 0xfb, 0x0c, 0x08, 0xff, 0xeb, 0x1c, 0x18, 0xef, 0x10, 0xe7, 0xe3, 0x14}},
|
||||||
|
{[16]byte{0x00, 0x3e, 0x7c, 0x42, 0xf8, 0xc6, 0x84, 0xba, 0xed, 0xd3, 0x91, 0xaf, 0x15, 0x2b, 0x69, 0x57}, [16]byte{0x00, 0xc7, 0x93, 0x54, 0x3b, 0xfc, 0xa8, 0x6f, 0x76, 0xb1, 0xe5, 0x22, 0x4d, 0x8a, 0xde, 0x19}},
|
||||||
|
{[16]byte{0x00, 0x3f, 0x7e, 0x41, 0xfc, 0xc3, 0x82, 0xbd, 0xe5, 0xda, 0x9b, 0xa4, 0x19, 0x26, 0x67, 0x58}, [16]byte{0x00, 0xd7, 0xb3, 0x64, 0x7b, 0xac, 0xc8, 0x1f, 0xf6, 0x21, 0x45, 0x92, 0x8d, 0x5a, 0x3e, 0xe9}},
|
||||||
|
{[16]byte{0x00, 0x40, 0x80, 0xc0, 0x1d, 0x5d, 0x9d, 0xdd, 0x3a, 0x7a, 0xba, 0xfa, 0x27, 0x67, 0xa7, 0xe7}, [16]byte{0x00, 0x74, 0xe8, 0x9c, 0xcd, 0xb9, 0x25, 0x51, 0x87, 0xf3, 0x6f, 0x1b, 0x4a, 0x3e, 0xa2, 0xd6}},
|
||||||
|
{[16]byte{0x00, 0x41, 0x82, 0xc3, 0x19, 0x58, 0x9b, 0xda, 0x32, 0x73, 0xb0, 0xf1, 0x2b, 0x6a, 0xa9, 0xe8}, [16]byte{0x00, 0x64, 0xc8, 0xac, 0x8d, 0xe9, 0x45, 0x21, 0x07, 0x63, 0xcf, 0xab, 0x8a, 0xee, 0x42, 0x26}},
|
||||||
|
{[16]byte{0x00, 0x42, 0x84, 0xc6, 0x15, 0x57, 0x91, 0xd3, 0x2a, 0x68, 0xae, 0xec, 0x3f, 0x7d, 0xbb, 0xf9}, [16]byte{0x00, 0x54, 0xa8, 0xfc, 0x4d, 0x19, 0xe5, 0xb1, 0x9a, 0xce, 0x32, 0x66, 0xd7, 0x83, 0x7f, 0x2b}},
|
||||||
|
{[16]byte{0x00, 0x43, 0x86, 0xc5, 0x11, 0x52, 0x97, 0xd4, 0x22, 0x61, 0xa4, 0xe7, 0x33, 0x70, 0xb5, 0xf6}, [16]byte{0x00, 0x44, 0x88, 0xcc, 0x0d, 0x49, 0x85, 0xc1, 0x1a, 0x5e, 0x92, 0xd6, 0x17, 0x53, 0x9f, 0xdb}},
|
||||||
|
{[16]byte{0x00, 0x44, 0x88, 0xcc, 0x0d, 0x49, 0x85, 0xc1, 0x1a, 0x5e, 0x92, 0xd6, 0x17, 0x53, 0x9f, 0xdb}, [16]byte{0x00, 0x34, 0x68, 0x5c, 0xd0, 0xe4, 0xb8, 0x8c, 0xbd, 0x89, 0xd5, 0xe1, 0x6d, 0x59, 0x05, 0x31}},
|
||||||
|
{[16]byte{0x00, 0x45, 0x8a, 0xcf, 0x09, 0x4c, 0x83, 0xc6, 0x12, 0x57, 0x98, 0xdd, 0x1b, 0x5e, 0x91, 0xd4}, [16]byte{0x00, 0x24, 0x48, 0x6c, 0x90, 0xb4, 0xd8, 0xfc, 0x3d, 0x19, 0x75, 0x51, 0xad, 0x89, 0xe5, 0xc1}},
|
||||||
|
{[16]byte{0x00, 0x46, 0x8c, 0xca, 0x05, 0x43, 0x89, 0xcf, 0x0a, 0x4c, 0x86, 0xc0, 0x0f, 0x49, 0x83, 0xc5}, [16]byte{0x00, 0x14, 0x28, 0x3c, 0x50, 0x44, 0x78, 0x6c, 0xa0, 0xb4, 0x88, 0x9c, 0xf0, 0xe4, 0xd8, 0xcc}},
|
||||||
|
{[16]byte{0x00, 0x47, 0x8e, 0xc9, 0x01, 0x46, 0x8f, 0xc8, 0x02, 0x45, 0x8c, 0xcb, 0x03, 0x44, 0x8d, 0xca}, [16]byte{0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c}},
|
||||||
|
{[16]byte{0x00, 0x48, 0x90, 0xd8, 0x3d, 0x75, 0xad, 0xe5, 0x7a, 0x32, 0xea, 0xa2, 0x47, 0x0f, 0xd7, 0x9f}, [16]byte{0x00, 0xf4, 0xf5, 0x01, 0xf7, 0x03, 0x02, 0xf6, 0xf3, 0x07, 0x06, 0xf2, 0x04, 0xf0, 0xf1, 0x05}},
|
||||||
|
{[16]byte{0x00, 0x49, 0x92, 0xdb, 0x39, 0x70, 0xab, 0xe2, 0x72, 0x3b, 0xe0, 0xa9, 0x4b, 0x02, 0xd9, 0x90}, [16]byte{0x00, 0xe4, 0xd5, 0x31, 0xb7, 0x53, 0x62, 0x86, 0x73, 0x97, 0xa6, 0x42, 0xc4, 0x20, 0x11, 0xf5}},
|
||||||
|
{[16]byte{0x00, 0x4a, 0x94, 0xde, 0x35, 0x7f, 0xa1, 0xeb, 0x6a, 0x20, 0xfe, 0xb4, 0x5f, 0x15, 0xcb, 0x81}, [16]byte{0x00, 0xd4, 0xb5, 0x61, 0x77, 0xa3, 0xc2, 0x16, 0xee, 0x3a, 0x5b, 0x8f, 0x99, 0x4d, 0x2c, 0xf8}},
|
||||||
|
{[16]byte{0x00, 0x4b, 0x96, 0xdd, 0x31, 0x7a, 0xa7, 0xec, 0x62, 0x29, 0xf4, 0xbf, 0x53, 0x18, 0xc5, 0x8e}, [16]byte{0x00, 0xc4, 0x95, 0x51, 0x37, 0xf3, 0xa2, 0x66, 0x6e, 0xaa, 0xfb, 0x3f, 0x59, 0x9d, 0xcc, 0x08}},
|
||||||
|
{[16]byte{0x00, 0x4c, 0x98, 0xd4, 0x2d, 0x61, 0xb5, 0xf9, 0x5a, 0x16, 0xc2, 0x8e, 0x77, 0x3b, 0xef, 0xa3}, [16]byte{0x00, 0xb4, 0x75, 0xc1, 0xea, 0x5e, 0x9f, 0x2b, 0xc9, 0x7d, 0xbc, 0x08, 0x23, 0x97, 0x56, 0xe2}},
|
||||||
|
{[16]byte{0x00, 0x4d, 0x9a, 0xd7, 0x29, 0x64, 0xb3, 0xfe, 0x52, 0x1f, 0xc8, 0x85, 0x7b, 0x36, 0xe1, 0xac}, [16]byte{0x00, 0xa4, 0x55, 0xf1, 0xaa, 0x0e, 0xff, 0x5b, 0x49, 0xed, 0x1c, 0xb8, 0xe3, 0x47, 0xb6, 0x12}},
|
||||||
|
{[16]byte{0x00, 0x4e, 0x9c, 0xd2, 0x25, 0x6b, 0xb9, 0xf7, 0x4a, 0x04, 0xd6, 0x98, 0x6f, 0x21, 0xf3, 0xbd}, [16]byte{0x00, 0x94, 0x35, 0xa1, 0x6a, 0xfe, 0x5f, 0xcb, 0xd4, 0x40, 0xe1, 0x75, 0xbe, 0x2a, 0x8b, 0x1f}},
|
||||||
|
{[16]byte{0x00, 0x4f, 0x9e, 0xd1, 0x21, 0x6e, 0xbf, 0xf0, 0x42, 0x0d, 0xdc, 0x93, 0x63, 0x2c, 0xfd, 0xb2}, [16]byte{0x00, 0x84, 0x15, 0x91, 0x2a, 0xae, 0x3f, 0xbb, 0x54, 0xd0, 0x41, 0xc5, 0x7e, 0xfa, 0x6b, 0xef}},
|
||||||
|
{[16]byte{0x00, 0x50, 0xa0, 0xf0, 0x5d, 0x0d, 0xfd, 0xad, 0xba, 0xea, 0x1a, 0x4a, 0xe7, 0xb7, 0x47, 0x17}, [16]byte{0x00, 0x69, 0xd2, 0xbb, 0xb9, 0xd0, 0x6b, 0x02, 0x6f, 0x06, 0xbd, 0xd4, 0xd6, 0xbf, 0x04, 0x6d}},
|
||||||
|
{[16]byte{0x00, 0x51, 0xa2, 0xf3, 0x59, 0x08, 0xfb, 0xaa, 0xb2, 0xe3, 0x10, 0x41, 0xeb, 0xba, 0x49, 0x18}, [16]byte{0x00, 0x79, 0xf2, 0x8b, 0xf9, 0x80, 0x0b, 0x72, 0xef, 0x96, 0x1d, 0x64, 0x16, 0x6f, 0xe4, 0x9d}},
|
||||||
|
{[16]byte{0x00, 0x52, 0xa4, 0xf6, 0x55, 0x07, 0xf1, 0xa3, 0xaa, 0xf8, 0x0e, 0x5c, 0xff, 0xad, 0x5b, 0x09}, [16]byte{0x00, 0x49, 0x92, 0xdb, 0x39, 0x70, 0xab, 0xe2, 0x72, 0x3b, 0xe0, 0xa9, 0x4b, 0x02, 0xd9, 0x90}},
|
||||||
|
{[16]byte{0x00, 0x53, 0xa6, 0xf5, 0x51, 0x02, 0xf7, 0xa4, 0xa2, 0xf1, 0x04, 0x57, 0xf3, 0xa0, 0x55, 0x06}, [16]byte{0x00, 0x59, 0xb2, 0xeb, 0x79, 0x20, 0xcb, 0x92, 0xf2, 0xab, 0x40, 0x19, 0x8b, 0xd2, 0x39, 0x60}},
|
||||||
|
{[16]byte{0x00, 0x54, 0xa8, 0xfc, 0x4d, 0x19, 0xe5, 0xb1, 0x9a, 0xce, 0x32, 0x66, 0xd7, 0x83, 0x7f, 0x2b}, [16]byte{0x00, 0x29, 0x52, 0x7b, 0xa4, 0x8d, 0xf6, 0xdf, 0x55, 0x7c, 0x07, 0x2e, 0xf1, 0xd8, 0xa3, 0x8a}},
|
||||||
|
{[16]byte{0x00, 0x55, 0xaa, 0xff, 0x49, 0x1c, 0xe3, 0xb6, 0x92, 0xc7, 0x38, 0x6d, 0xdb, 0x8e, 0x71, 0x24}, [16]byte{0x00, 0x39, 0x72, 0x4b, 0xe4, 0xdd, 0x96, 0xaf, 0xd5, 0xec, 0xa7, 0x9e, 0x31, 0x08, 0x43, 0x7a}},
|
||||||
|
{[16]byte{0x00, 0x56, 0xac, 0xfa, 0x45, 0x13, 0xe9, 0xbf, 0x8a, 0xdc, 0x26, 0x70, 0xcf, 0x99, 0x63, 0x35}, [16]byte{0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77}},
|
||||||
|
{[16]byte{0x00, 0x57, 0xae, 0xf9, 0x41, 0x16, 0xef, 0xb8, 0x82, 0xd5, 0x2c, 0x7b, 0xc3, 0x94, 0x6d, 0x3a}, [16]byte{0x00, 0x19, 0x32, 0x2b, 0x64, 0x7d, 0x56, 0x4f, 0xc8, 0xd1, 0xfa, 0xe3, 0xac, 0xb5, 0x9e, 0x87}},
|
||||||
|
{[16]byte{0x00, 0x58, 0xb0, 0xe8, 0x7d, 0x25, 0xcd, 0x95, 0xfa, 0xa2, 0x4a, 0x12, 0x87, 0xdf, 0x37, 0x6f}, [16]byte{0x00, 0xe9, 0xcf, 0x26, 0x83, 0x6a, 0x4c, 0xa5, 0x1b, 0xf2, 0xd4, 0x3d, 0x98, 0x71, 0x57, 0xbe}},
|
||||||
|
{[16]byte{0x00, 0x59, 0xb2, 0xeb, 0x79, 0x20, 0xcb, 0x92, 0xf2, 0xab, 0x40, 0x19, 0x8b, 0xd2, 0x39, 0x60}, [16]byte{0x00, 0xf9, 0xef, 0x16, 0xc3, 0x3a, 0x2c, 0xd5, 0x9b, 0x62, 0x74, 0x8d, 0x58, 0xa1, 0xb7, 0x4e}},
|
||||||
|
{[16]byte{0x00, 0x5a, 0xb4, 0xee, 0x75, 0x2f, 0xc1, 0x9b, 0xea, 0xb0, 0x5e, 0x04, 0x9f, 0xc5, 0x2b, 0x71}, [16]byte{0x00, 0xc9, 0x8f, 0x46, 0x03, 0xca, 0x8c, 0x45, 0x06, 0xcf, 0x89, 0x40, 0x05, 0xcc, 0x8a, 0x43}},
|
||||||
|
{[16]byte{0x00, 0x5b, 0xb6, 0xed, 0x71, 0x2a, 0xc7, 0x9c, 0xe2, 0xb9, 0x54, 0x0f, 0x93, 0xc8, 0x25, 0x7e}, [16]byte{0x00, 0xd9, 0xaf, 0x76, 0x43, 0x9a, 0xec, 0x35, 0x86, 0x5f, 0x29, 0xf0, 0xc5, 0x1c, 0x6a, 0xb3}},
|
||||||
|
{[16]byte{0x00, 0x5c, 0xb8, 0xe4, 0x6d, 0x31, 0xd5, 0x89, 0xda, 0x86, 0x62, 0x3e, 0xb7, 0xeb, 0x0f, 0x53}, [16]byte{0x00, 0xa9, 0x4f, 0xe6, 0x9e, 0x37, 0xd1, 0x78, 0x21, 0x88, 0x6e, 0xc7, 0xbf, 0x16, 0xf0, 0x59}},
|
||||||
|
{[16]byte{0x00, 0x5d, 0xba, 0xe7, 0x69, 0x34, 0xd3, 0x8e, 0xd2, 0x8f, 0x68, 0x35, 0xbb, 0xe6, 0x01, 0x5c}, [16]byte{0x00, 0xb9, 0x6f, 0xd6, 0xde, 0x67, 0xb1, 0x08, 0xa1, 0x18, 0xce, 0x77, 0x7f, 0xc6, 0x10, 0xa9}},
|
||||||
|
{[16]byte{0x00, 0x5e, 0xbc, 0xe2, 0x65, 0x3b, 0xd9, 0x87, 0xca, 0x94, 0x76, 0x28, 0xaf, 0xf1, 0x13, 0x4d}, [16]byte{0x00, 0x89, 0x0f, 0x86, 0x1e, 0x97, 0x11, 0x98, 0x3c, 0xb5, 0x33, 0xba, 0x22, 0xab, 0x2d, 0xa4}},
|
||||||
|
{[16]byte{0x00, 0x5f, 0xbe, 0xe1, 0x61, 0x3e, 0xdf, 0x80, 0xc2, 0x9d, 0x7c, 0x23, 0xa3, 0xfc, 0x1d, 0x42}, [16]byte{0x00, 0x99, 0x2f, 0xb6, 0x5e, 0xc7, 0x71, 0xe8, 0xbc, 0x25, 0x93, 0x0a, 0xe2, 0x7b, 0xcd, 0x54}},
|
||||||
|
{[16]byte{0x00, 0x60, 0xc0, 0xa0, 0x9d, 0xfd, 0x5d, 0x3d, 0x27, 0x47, 0xe7, 0x87, 0xba, 0xda, 0x7a, 0x1a}, [16]byte{0x00, 0x4e, 0x9c, 0xd2, 0x25, 0x6b, 0xb9, 0xf7, 0x4a, 0x04, 0xd6, 0x98, 0x6f, 0x21, 0xf3, 0xbd}},
|
||||||
|
{[16]byte{0x00, 0x61, 0xc2, 0xa3, 0x99, 0xf8, 0x5b, 0x3a, 0x2f, 0x4e, 0xed, 0x8c, 0xb6, 0xd7, 0x74, 0x15}, [16]byte{0x00, 0x5e, 0xbc, 0xe2, 0x65, 0x3b, 0xd9, 0x87, 0xca, 0x94, 0x76, 0x28, 0xaf, 0xf1, 0x13, 0x4d}},
|
||||||
|
{[16]byte{0x00, 0x62, 0xc4, 0xa6, 0x95, 0xf7, 0x51, 0x33, 0x37, 0x55, 0xf3, 0x91, 0xa2, 0xc0, 0x66, 0x04}, [16]byte{0x00, 0x6e, 0xdc, 0xb2, 0xa5, 0xcb, 0x79, 0x17, 0x57, 0x39, 0x8b, 0xe5, 0xf2, 0x9c, 0x2e, 0x40}},
|
||||||
|
{[16]byte{0x00, 0x63, 0xc6, 0xa5, 0x91, 0xf2, 0x57, 0x34, 0x3f, 0x5c, 0xf9, 0x9a, 0xae, 0xcd, 0x68, 0x0b}, [16]byte{0x00, 0x7e, 0xfc, 0x82, 0xe5, 0x9b, 0x19, 0x67, 0xd7, 0xa9, 0x2b, 0x55, 0x32, 0x4c, 0xce, 0xb0}},
|
||||||
|
{[16]byte{0x00, 0x64, 0xc8, 0xac, 0x8d, 0xe9, 0x45, 0x21, 0x07, 0x63, 0xcf, 0xab, 0x8a, 0xee, 0x42, 0x26}, [16]byte{0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a}},
|
||||||
|
{[16]byte{0x00, 0x65, 0xca, 0xaf, 0x89, 0xec, 0x43, 0x26, 0x0f, 0x6a, 0xc5, 0xa0, 0x86, 0xe3, 0x4c, 0x29}, [16]byte{0x00, 0x1e, 0x3c, 0x22, 0x78, 0x66, 0x44, 0x5a, 0xf0, 0xee, 0xcc, 0xd2, 0x88, 0x96, 0xb4, 0xaa}},
|
||||||
|
{[16]byte{0x00, 0x66, 0xcc, 0xaa, 0x85, 0xe3, 0x49, 0x2f, 0x17, 0x71, 0xdb, 0xbd, 0x92, 0xf4, 0x5e, 0x38}, [16]byte{0x00, 0x2e, 0x5c, 0x72, 0xb8, 0x96, 0xe4, 0xca, 0x6d, 0x43, 0x31, 0x1f, 0xd5, 0xfb, 0x89, 0xa7}},
|
||||||
|
{[16]byte{0x00, 0x67, 0xce, 0xa9, 0x81, 0xe6, 0x4f, 0x28, 0x1f, 0x78, 0xd1, 0xb6, 0x9e, 0xf9, 0x50, 0x37}, [16]byte{0x00, 0x3e, 0x7c, 0x42, 0xf8, 0xc6, 0x84, 0xba, 0xed, 0xd3, 0x91, 0xaf, 0x15, 0x2b, 0x69, 0x57}},
|
||||||
|
{[16]byte{0x00, 0x68, 0xd0, 0xb8, 0xbd, 0xd5, 0x6d, 0x05, 0x67, 0x0f, 0xb7, 0xdf, 0xda, 0xb2, 0x0a, 0x62}, [16]byte{0x00, 0xce, 0x81, 0x4f, 0x1f, 0xd1, 0x9e, 0x50, 0x3e, 0xf0, 0xbf, 0x71, 0x21, 0xef, 0xa0, 0x6e}},
|
||||||
|
{[16]byte{0x00, 0x69, 0xd2, 0xbb, 0xb9, 0xd0, 0x6b, 0x02, 0x6f, 0x06, 0xbd, 0xd4, 0xd6, 0xbf, 0x04, 0x6d}, [16]byte{0x00, 0xde, 0xa1, 0x7f, 0x5f, 0x81, 0xfe, 0x20, 0xbe, 0x60, 0x1f, 0xc1, 0xe1, 0x3f, 0x40, 0x9e}},
|
||||||
|
{[16]byte{0x00, 0x6a, 0xd4, 0xbe, 0xb5, 0xdf, 0x61, 0x0b, 0x77, 0x1d, 0xa3, 0xc9, 0xc2, 0xa8, 0x16, 0x7c}, [16]byte{0x00, 0xee, 0xc1, 0x2f, 0x9f, 0x71, 0x5e, 0xb0, 0x23, 0xcd, 0xe2, 0x0c, 0xbc, 0x52, 0x7d, 0x93}},
|
||||||
|
{[16]byte{0x00, 0x6b, 0xd6, 0xbd, 0xb1, 0xda, 0x67, 0x0c, 0x7f, 0x14, 0xa9, 0xc2, 0xce, 0xa5, 0x18, 0x73}, [16]byte{0x00, 0xfe, 0xe1, 0x1f, 0xdf, 0x21, 0x3e, 0xc0, 0xa3, 0x5d, 0x42, 0xbc, 0x7c, 0x82, 0x9d, 0x63}},
|
||||||
|
{[16]byte{0x00, 0x6c, 0xd8, 0xb4, 0xad, 0xc1, 0x75, 0x19, 0x47, 0x2b, 0x9f, 0xf3, 0xea, 0x86, 0x32, 0x5e}, [16]byte{0x00, 0x8e, 0x01, 0x8f, 0x02, 0x8c, 0x03, 0x8d, 0x04, 0x8a, 0x05, 0x8b, 0x06, 0x88, 0x07, 0x89}},
|
||||||
|
{[16]byte{0x00, 0x6d, 0xda, 0xb7, 0xa9, 0xc4, 0x73, 0x1e, 0x4f, 0x22, 0x95, 0xf8, 0xe6, 0x8b, 0x3c, 0x51}, [16]byte{0x00, 0x9e, 0x21, 0xbf, 0x42, 0xdc, 0x63, 0xfd, 0x84, 0x1a, 0xa5, 0x3b, 0xc6, 0x58, 0xe7, 0x79}},
|
||||||
|
{[16]byte{0x00, 0x6e, 0xdc, 0xb2, 0xa5, 0xcb, 0x79, 0x17, 0x57, 0x39, 0x8b, 0xe5, 0xf2, 0x9c, 0x2e, 0x40}, [16]byte{0x00, 0xae, 0x41, 0xef, 0x82, 0x2c, 0xc3, 0x6d, 0x19, 0xb7, 0x58, 0xf6, 0x9b, 0x35, 0xda, 0x74}},
|
||||||
|
{[16]byte{0x00, 0x6f, 0xde, 0xb1, 0xa1, 0xce, 0x7f, 0x10, 0x5f, 0x30, 0x81, 0xee, 0xfe, 0x91, 0x20, 0x4f}, [16]byte{0x00, 0xbe, 0x61, 0xdf, 0xc2, 0x7c, 0xa3, 0x1d, 0x99, 0x27, 0xf8, 0x46, 0x5b, 0xe5, 0x3a, 0x84}},
|
||||||
|
{[16]byte{0x00, 0x70, 0xe0, 0x90, 0xdd, 0xad, 0x3d, 0x4d, 0xa7, 0xd7, 0x47, 0x37, 0x7a, 0x0a, 0x9a, 0xea}, [16]byte{0x00, 0x53, 0xa6, 0xf5, 0x51, 0x02, 0xf7, 0xa4, 0xa2, 0xf1, 0x04, 0x57, 0xf3, 0xa0, 0x55, 0x06}},
|
||||||
|
{[16]byte{0x00, 0x71, 0xe2, 0x93, 0xd9, 0xa8, 0x3b, 0x4a, 0xaf, 0xde, 0x4d, 0x3c, 0x76, 0x07, 0x94, 0xe5}, [16]byte{0x00, 0x43, 0x86, 0xc5, 0x11, 0x52, 0x97, 0xd4, 0x22, 0x61, 0xa4, 0xe7, 0x33, 0x70, 0xb5, 0xf6}},
|
||||||
|
{[16]byte{0x00, 0x72, 0xe4, 0x96, 0xd5, 0xa7, 0x31, 0x43, 0xb7, 0xc5, 0x53, 0x21, 0x62, 0x10, 0x86, 0xf4}, [16]byte{0x00, 0x73, 0xe6, 0x95, 0xd1, 0xa2, 0x37, 0x44, 0xbf, 0xcc, 0x59, 0x2a, 0x6e, 0x1d, 0x88, 0xfb}},
|
||||||
|
{[16]byte{0x00, 0x73, 0xe6, 0x95, 0xd1, 0xa2, 0x37, 0x44, 0xbf, 0xcc, 0x59, 0x2a, 0x6e, 0x1d, 0x88, 0xfb}, [16]byte{0x00, 0x63, 0xc6, 0xa5, 0x91, 0xf2, 0x57, 0x34, 0x3f, 0x5c, 0xf9, 0x9a, 0xae, 0xcd, 0x68, 0x0b}},
|
||||||
|
{[16]byte{0x00, 0x74, 0xe8, 0x9c, 0xcd, 0xb9, 0x25, 0x51, 0x87, 0xf3, 0x6f, 0x1b, 0x4a, 0x3e, 0xa2, 0xd6}, [16]byte{0x00, 0x13, 0x26, 0x35, 0x4c, 0x5f, 0x6a, 0x79, 0x98, 0x8b, 0xbe, 0xad, 0xd4, 0xc7, 0xf2, 0xe1}},
|
||||||
|
{[16]byte{0x00, 0x75, 0xea, 0x9f, 0xc9, 0xbc, 0x23, 0x56, 0x8f, 0xfa, 0x65, 0x10, 0x46, 0x33, 0xac, 0xd9}, [16]byte{0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11}},
|
||||||
|
{[16]byte{0x00, 0x76, 0xec, 0x9a, 0xc5, 0xb3, 0x29, 0x5f, 0x97, 0xe1, 0x7b, 0x0d, 0x52, 0x24, 0xbe, 0xc8}, [16]byte{0x00, 0x33, 0x66, 0x55, 0xcc, 0xff, 0xaa, 0x99, 0x85, 0xb6, 0xe3, 0xd0, 0x49, 0x7a, 0x2f, 0x1c}},
|
||||||
|
{[16]byte{0x00, 0x77, 0xee, 0x99, 0xc1, 0xb6, 0x2f, 0x58, 0x9f, 0xe8, 0x71, 0x06, 0x5e, 0x29, 0xb0, 0xc7}, [16]byte{0x00, 0x23, 0x46, 0x65, 0x8c, 0xaf, 0xca, 0xe9, 0x05, 0x26, 0x43, 0x60, 0x89, 0xaa, 0xcf, 0xec}},
|
||||||
|
{[16]byte{0x00, 0x78, 0xf0, 0x88, 0xfd, 0x85, 0x0d, 0x75, 0xe7, 0x9f, 0x17, 0x6f, 0x1a, 0x62, 0xea, 0x92}, [16]byte{0x00, 0xd3, 0xbb, 0x68, 0x6b, 0xb8, 0xd0, 0x03, 0xd6, 0x05, 0x6d, 0xbe, 0xbd, 0x6e, 0x06, 0xd5}},
|
||||||
|
{[16]byte{0x00, 0x79, 0xf2, 0x8b, 0xf9, 0x80, 0x0b, 0x72, 0xef, 0x96, 0x1d, 0x64, 0x16, 0x6f, 0xe4, 0x9d}, [16]byte{0x00, 0xc3, 0x9b, 0x58, 0x2b, 0xe8, 0xb0, 0x73, 0x56, 0x95, 0xcd, 0x0e, 0x7d, 0xbe, 0xe6, 0x25}},
|
||||||
|
{[16]byte{0x00, 0x7a, 0xf4, 0x8e, 0xf5, 0x8f, 0x01, 0x7b, 0xf7, 0x8d, 0x03, 0x79, 0x02, 0x78, 0xf6, 0x8c}, [16]byte{0x00, 0xf3, 0xfb, 0x08, 0xeb, 0x18, 0x10, 0xe3, 0xcb, 0x38, 0x30, 0xc3, 0x20, 0xd3, 0xdb, 0x28}},
|
||||||
|
{[16]byte{0x00, 0x7b, 0xf6, 0x8d, 0xf1, 0x8a, 0x07, 0x7c, 0xff, 0x84, 0x09, 0x72, 0x0e, 0x75, 0xf8, 0x83}, [16]byte{0x00, 0xe3, 0xdb, 0x38, 0xab, 0x48, 0x70, 0x93, 0x4b, 0xa8, 0x90, 0x73, 0xe0, 0x03, 0x3b, 0xd8}},
|
||||||
|
{[16]byte{0x00, 0x7c, 0xf8, 0x84, 0xed, 0x91, 0x15, 0x69, 0xc7, 0xbb, 0x3f, 0x43, 0x2a, 0x56, 0xd2, 0xae}, [16]byte{0x00, 0x93, 0x3b, 0xa8, 0x76, 0xe5, 0x4d, 0xde, 0xec, 0x7f, 0xd7, 0x44, 0x9a, 0x09, 0xa1, 0x32}},
|
||||||
|
{[16]byte{0x00, 0x7d, 0xfa, 0x87, 0xe9, 0x94, 0x13, 0x6e, 0xcf, 0xb2, 0x35, 0x48, 0x26, 0x5b, 0xdc, 0xa1}, [16]byte{0x00, 0x83, 0x1b, 0x98, 0x36, 0xb5, 0x2d, 0xae, 0x6c, 0xef, 0x77, 0xf4, 0x5a, 0xd9, 0x41, 0xc2}},
|
||||||
|
{[16]byte{0x00, 0x7e, 0xfc, 0x82, 0xe5, 0x9b, 0x19, 0x67, 0xd7, 0xa9, 0x2b, 0x55, 0x32, 0x4c, 0xce, 0xb0}, [16]byte{0x00, 0xb3, 0x7b, 0xc8, 0xf6, 0x45, 0x8d, 0x3e, 0xf1, 0x42, 0x8a, 0x39, 0x07, 0xb4, 0x7c, 0xcf}},
|
||||||
|
{[16]byte{0x00, 0x7f, 0xfe, 0x81, 0xe1, 0x9e, 0x1f, 0x60, 0xdf, 0xa0, 0x21, 0x5e, 0x3e, 0x41, 0xc0, 0xbf}, [16]byte{0x00, 0xa3, 0x5b, 0xf8, 0xb6, 0x15, 0xed, 0x4e, 0x71, 0xd2, 0x2a, 0x89, 0xc7, 0x64, 0x9c, 0x3f}},
|
||||||
|
{[16]byte{0x00, 0x80, 0x1d, 0x9d, 0x3a, 0xba, 0x27, 0xa7, 0x74, 0xf4, 0x69, 0xe9, 0x4e, 0xce, 0x53, 0xd3}, [16]byte{0x00, 0xe8, 0xcd, 0x25, 0x87, 0x6f, 0x4a, 0xa2, 0x13, 0xfb, 0xde, 0x36, 0x94, 0x7c, 0x59, 0xb1}},
|
||||||
|
{[16]byte{0x00, 0x81, 0x1f, 0x9e, 0x3e, 0xbf, 0x21, 0xa0, 0x7c, 0xfd, 0x63, 0xe2, 0x42, 0xc3, 0x5d, 0xdc}, [16]byte{0x00, 0xf8, 0xed, 0x15, 0xc7, 0x3f, 0x2a, 0xd2, 0x93, 0x6b, 0x7e, 0x86, 0x54, 0xac, 0xb9, 0x41}},
|
||||||
|
{[16]byte{0x00, 0x82, 0x19, 0x9b, 0x32, 0xb0, 0x2b, 0xa9, 0x64, 0xe6, 0x7d, 0xff, 0x56, 0xd4, 0x4f, 0xcd}, [16]byte{0x00, 0xc8, 0x8d, 0x45, 0x07, 0xcf, 0x8a, 0x42, 0x0e, 0xc6, 0x83, 0x4b, 0x09, 0xc1, 0x84, 0x4c}},
|
||||||
|
{[16]byte{0x00, 0x83, 0x1b, 0x98, 0x36, 0xb5, 0x2d, 0xae, 0x6c, 0xef, 0x77, 0xf4, 0x5a, 0xd9, 0x41, 0xc2}, [16]byte{0x00, 0xd8, 0xad, 0x75, 0x47, 0x9f, 0xea, 0x32, 0x8e, 0x56, 0x23, 0xfb, 0xc9, 0x11, 0x64, 0xbc}},
|
||||||
|
{[16]byte{0x00, 0x84, 0x15, 0x91, 0x2a, 0xae, 0x3f, 0xbb, 0x54, 0xd0, 0x41, 0xc5, 0x7e, 0xfa, 0x6b, 0xef}, [16]byte{0x00, 0xa8, 0x4d, 0xe5, 0x9a, 0x32, 0xd7, 0x7f, 0x29, 0x81, 0x64, 0xcc, 0xb3, 0x1b, 0xfe, 0x56}},
|
||||||
|
{[16]byte{0x00, 0x85, 0x17, 0x92, 0x2e, 0xab, 0x39, 0xbc, 0x5c, 0xd9, 0x4b, 0xce, 0x72, 0xf7, 0x65, 0xe0}, [16]byte{0x00, 0xb8, 0x6d, 0xd5, 0xda, 0x62, 0xb7, 0x0f, 0xa9, 0x11, 0xc4, 0x7c, 0x73, 0xcb, 0x1e, 0xa6}},
|
||||||
|
{[16]byte{0x00, 0x86, 0x11, 0x97, 0x22, 0xa4, 0x33, 0xb5, 0x44, 0xc2, 0x55, 0xd3, 0x66, 0xe0, 0x77, 0xf1}, [16]byte{0x00, 0x88, 0x0d, 0x85, 0x1a, 0x92, 0x17, 0x9f, 0x34, 0xbc, 0x39, 0xb1, 0x2e, 0xa6, 0x23, 0xab}},
|
||||||
|
{[16]byte{0x00, 0x87, 0x13, 0x94, 0x26, 0xa1, 0x35, 0xb2, 0x4c, 0xcb, 0x5f, 0xd8, 0x6a, 0xed, 0x79, 0xfe}, [16]byte{0x00, 0x98, 0x2d, 0xb5, 0x5a, 0xc2, 0x77, 0xef, 0xb4, 0x2c, 0x99, 0x01, 0xee, 0x76, 0xc3, 0x5b}},
|
||||||
|
{[16]byte{0x00, 0x88, 0x0d, 0x85, 0x1a, 0x92, 0x17, 0x9f, 0x34, 0xbc, 0x39, 0xb1, 0x2e, 0xa6, 0x23, 0xab}, [16]byte{0x00, 0x68, 0xd0, 0xb8, 0xbd, 0xd5, 0x6d, 0x05, 0x67, 0x0f, 0xb7, 0xdf, 0xda, 0xb2, 0x0a, 0x62}},
|
||||||
|
{[16]byte{0x00, 0x89, 0x0f, 0x86, 0x1e, 0x97, 0x11, 0x98, 0x3c, 0xb5, 0x33, 0xba, 0x22, 0xab, 0x2d, 0xa4}, [16]byte{0x00, 0x78, 0xf0, 0x88, 0xfd, 0x85, 0x0d, 0x75, 0xe7, 0x9f, 0x17, 0x6f, 0x1a, 0x62, 0xea, 0x92}},
|
||||||
|
{[16]byte{0x00, 0x8a, 0x09, 0x83, 0x12, 0x98, 0x1b, 0x91, 0x24, 0xae, 0x2d, 0xa7, 0x36, 0xbc, 0x3f, 0xb5}, [16]byte{0x00, 0x48, 0x90, 0xd8, 0x3d, 0x75, 0xad, 0xe5, 0x7a, 0x32, 0xea, 0xa2, 0x47, 0x0f, 0xd7, 0x9f}},
|
||||||
|
{[16]byte{0x00, 0x8b, 0x0b, 0x80, 0x16, 0x9d, 0x1d, 0x96, 0x2c, 0xa7, 0x27, 0xac, 0x3a, 0xb1, 0x31, 0xba}, [16]byte{0x00, 0x58, 0xb0, 0xe8, 0x7d, 0x25, 0xcd, 0x95, 0xfa, 0xa2, 0x4a, 0x12, 0x87, 0xdf, 0x37, 0x6f}},
|
||||||
|
{[16]byte{0x00, 0x8c, 0x05, 0x89, 0x0a, 0x86, 0x0f, 0x83, 0x14, 0x98, 0x11, 0x9d, 0x1e, 0x92, 0x1b, 0x97}, [16]byte{0x00, 0x28, 0x50, 0x78, 0xa0, 0x88, 0xf0, 0xd8, 0x5d, 0x75, 0x0d, 0x25, 0xfd, 0xd5, 0xad, 0x85}},
|
||||||
|
{[16]byte{0x00, 0x8d, 0x07, 0x8a, 0x0e, 0x83, 0x09, 0x84, 0x1c, 0x91, 0x1b, 0x96, 0x12, 0x9f, 0x15, 0x98}, [16]byte{0x00, 0x38, 0x70, 0x48, 0xe0, 0xd8, 0x90, 0xa8, 0xdd, 0xe5, 0xad, 0x95, 0x3d, 0x05, 0x4d, 0x75}},
|
||||||
|
{[16]byte{0x00, 0x8e, 0x01, 0x8f, 0x02, 0x8c, 0x03, 0x8d, 0x04, 0x8a, 0x05, 0x8b, 0x06, 0x88, 0x07, 0x89}, [16]byte{0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78}},
|
||||||
|
{[16]byte{0x00, 0x8f, 0x03, 0x8c, 0x06, 0x89, 0x05, 0x8a, 0x0c, 0x83, 0x0f, 0x80, 0x0a, 0x85, 0x09, 0x86}, [16]byte{0x00, 0x18, 0x30, 0x28, 0x60, 0x78, 0x50, 0x48, 0xc0, 0xd8, 0xf0, 0xe8, 0xa0, 0xb8, 0x90, 0x88}},
|
||||||
|
{[16]byte{0x00, 0x90, 0x3d, 0xad, 0x7a, 0xea, 0x47, 0xd7, 0xf4, 0x64, 0xc9, 0x59, 0x8e, 0x1e, 0xb3, 0x23}, [16]byte{0x00, 0xf5, 0xf7, 0x02, 0xf3, 0x06, 0x04, 0xf1, 0xfb, 0x0e, 0x0c, 0xf9, 0x08, 0xfd, 0xff, 0x0a}},
|
||||||
|
{[16]byte{0x00, 0x91, 0x3f, 0xae, 0x7e, 0xef, 0x41, 0xd0, 0xfc, 0x6d, 0xc3, 0x52, 0x82, 0x13, 0xbd, 0x2c}, [16]byte{0x00, 0xe5, 0xd7, 0x32, 0xb3, 0x56, 0x64, 0x81, 0x7b, 0x9e, 0xac, 0x49, 0xc8, 0x2d, 0x1f, 0xfa}},
|
||||||
|
{[16]byte{0x00, 0x92, 0x39, 0xab, 0x72, 0xe0, 0x4b, 0xd9, 0xe4, 0x76, 0xdd, 0x4f, 0x96, 0x04, 0xaf, 0x3d}, [16]byte{0x00, 0xd5, 0xb7, 0x62, 0x73, 0xa6, 0xc4, 0x11, 0xe6, 0x33, 0x51, 0x84, 0x95, 0x40, 0x22, 0xf7}},
|
||||||
|
{[16]byte{0x00, 0x93, 0x3b, 0xa8, 0x76, 0xe5, 0x4d, 0xde, 0xec, 0x7f, 0xd7, 0x44, 0x9a, 0x09, 0xa1, 0x32}, [16]byte{0x00, 0xc5, 0x97, 0x52, 0x33, 0xf6, 0xa4, 0x61, 0x66, 0xa3, 0xf1, 0x34, 0x55, 0x90, 0xc2, 0x07}},
|
||||||
|
{[16]byte{0x00, 0x94, 0x35, 0xa1, 0x6a, 0xfe, 0x5f, 0xcb, 0xd4, 0x40, 0xe1, 0x75, 0xbe, 0x2a, 0x8b, 0x1f}, [16]byte{0x00, 0xb5, 0x77, 0xc2, 0xee, 0x5b, 0x99, 0x2c, 0xc1, 0x74, 0xb6, 0x03, 0x2f, 0x9a, 0x58, 0xed}},
|
||||||
|
{[16]byte{0x00, 0x95, 0x37, 0xa2, 0x6e, 0xfb, 0x59, 0xcc, 0xdc, 0x49, 0xeb, 0x7e, 0xb2, 0x27, 0x85, 0x10}, [16]byte{0x00, 0xa5, 0x57, 0xf2, 0xae, 0x0b, 0xf9, 0x5c, 0x41, 0xe4, 0x16, 0xb3, 0xef, 0x4a, 0xb8, 0x1d}},
|
||||||
|
{[16]byte{0x00, 0x96, 0x31, 0xa7, 0x62, 0xf4, 0x53, 0xc5, 0xc4, 0x52, 0xf5, 0x63, 0xa6, 0x30, 0x97, 0x01}, [16]byte{0x00, 0x95, 0x37, 0xa2, 0x6e, 0xfb, 0x59, 0xcc, 0xdc, 0x49, 0xeb, 0x7e, 0xb2, 0x27, 0x85, 0x10}},
|
||||||
|
{[16]byte{0x00, 0x97, 0x33, 0xa4, 0x66, 0xf1, 0x55, 0xc2, 0xcc, 0x5b, 0xff, 0x68, 0xaa, 0x3d, 0x99, 0x0e}, [16]byte{0x00, 0x85, 0x17, 0x92, 0x2e, 0xab, 0x39, 0xbc, 0x5c, 0xd9, 0x4b, 0xce, 0x72, 0xf7, 0x65, 0xe0}},
|
||||||
|
{[16]byte{0x00, 0x98, 0x2d, 0xb5, 0x5a, 0xc2, 0x77, 0xef, 0xb4, 0x2c, 0x99, 0x01, 0xee, 0x76, 0xc3, 0x5b}, [16]byte{0x00, 0x75, 0xea, 0x9f, 0xc9, 0xbc, 0x23, 0x56, 0x8f, 0xfa, 0x65, 0x10, 0x46, 0x33, 0xac, 0xd9}},
|
||||||
|
{[16]byte{0x00, 0x99, 0x2f, 0xb6, 0x5e, 0xc7, 0x71, 0xe8, 0xbc, 0x25, 0x93, 0x0a, 0xe2, 0x7b, 0xcd, 0x54}, [16]byte{0x00, 0x65, 0xca, 0xaf, 0x89, 0xec, 0x43, 0x26, 0x0f, 0x6a, 0xc5, 0xa0, 0x86, 0xe3, 0x4c, 0x29}},
|
||||||
|
{[16]byte{0x00, 0x9a, 0x29, 0xb3, 0x52, 0xc8, 0x7b, 0xe1, 0xa4, 0x3e, 0x8d, 0x17, 0xf6, 0x6c, 0xdf, 0x45}, [16]byte{0x00, 0x55, 0xaa, 0xff, 0x49, 0x1c, 0xe3, 0xb6, 0x92, 0xc7, 0x38, 0x6d, 0xdb, 0x8e, 0x71, 0x24}},
|
||||||
|
{[16]byte{0x00, 0x9b, 0x2b, 0xb0, 0x56, 0xcd, 0x7d, 0xe6, 0xac, 0x37, 0x87, 0x1c, 0xfa, 0x61, 0xd1, 0x4a}, [16]byte{0x00, 0x45, 0x8a, 0xcf, 0x09, 0x4c, 0x83, 0xc6, 0x12, 0x57, 0x98, 0xdd, 0x1b, 0x5e, 0x91, 0xd4}},
|
||||||
|
{[16]byte{0x00, 0x9c, 0x25, 0xb9, 0x4a, 0xd6, 0x6f, 0xf3, 0x94, 0x08, 0xb1, 0x2d, 0xde, 0x42, 0xfb, 0x67}, [16]byte{0x00, 0x35, 0x6a, 0x5f, 0xd4, 0xe1, 0xbe, 0x8b, 0xb5, 0x80, 0xdf, 0xea, 0x61, 0x54, 0x0b, 0x3e}},
|
||||||
|
{[16]byte{0x00, 0x9d, 0x27, 0xba, 0x4e, 0xd3, 0x69, 0xf4, 0x9c, 0x01, 0xbb, 0x26, 0xd2, 0x4f, 0xf5, 0x68}, [16]byte{0x00, 0x25, 0x4a, 0x6f, 0x94, 0xb1, 0xde, 0xfb, 0x35, 0x10, 0x7f, 0x5a, 0xa1, 0x84, 0xeb, 0xce}},
|
||||||
|
{[16]byte{0x00, 0x9e, 0x21, 0xbf, 0x42, 0xdc, 0x63, 0xfd, 0x84, 0x1a, 0xa5, 0x3b, 0xc6, 0x58, 0xe7, 0x79}, [16]byte{0x00, 0x15, 0x2a, 0x3f, 0x54, 0x41, 0x7e, 0x6b, 0xa8, 0xbd, 0x82, 0x97, 0xfc, 0xe9, 0xd6, 0xc3}},
|
||||||
|
{[16]byte{0x00, 0x9f, 0x23, 0xbc, 0x46, 0xd9, 0x65, 0xfa, 0x8c, 0x13, 0xaf, 0x30, 0xca, 0x55, 0xe9, 0x76}, [16]byte{0x00, 0x05, 0x0a, 0x0f, 0x14, 0x11, 0x1e, 0x1b, 0x28, 0x2d, 0x22, 0x27, 0x3c, 0x39, 0x36, 0x33}},
|
||||||
|
{[16]byte{0x00, 0xa0, 0x5d, 0xfd, 0xba, 0x1a, 0xe7, 0x47, 0x69, 0xc9, 0x34, 0x94, 0xd3, 0x73, 0x8e, 0x2e}, [16]byte{0x00, 0xd2, 0xb9, 0x6b, 0x6f, 0xbd, 0xd6, 0x04, 0xde, 0x0c, 0x67, 0xb5, 0xb1, 0x63, 0x08, 0xda}},
|
||||||
|
{[16]byte{0x00, 0xa1, 0x5f, 0xfe, 0xbe, 0x1f, 0xe1, 0x40, 0x61, 0xc0, 0x3e, 0x9f, 0xdf, 0x7e, 0x80, 0x21}, [16]byte{0x00, 0xc2, 0x99, 0x5b, 0x2f, 0xed, 0xb6, 0x74, 0x5e, 0x9c, 0xc7, 0x05, 0x71, 0xb3, 0xe8, 0x2a}},
|
||||||
|
{[16]byte{0x00, 0xa2, 0x59, 0xfb, 0xb2, 0x10, 0xeb, 0x49, 0x79, 0xdb, 0x20, 0x82, 0xcb, 0x69, 0x92, 0x30}, [16]byte{0x00, 0xf2, 0xf9, 0x0b, 0xef, 0x1d, 0x16, 0xe4, 0xc3, 0x31, 0x3a, 0xc8, 0x2c, 0xde, 0xd5, 0x27}},
|
||||||
|
{[16]byte{0x00, 0xa3, 0x5b, 0xf8, 0xb6, 0x15, 0xed, 0x4e, 0x71, 0xd2, 0x2a, 0x89, 0xc7, 0x64, 0x9c, 0x3f}, [16]byte{0x00, 0xe2, 0xd9, 0x3b, 0xaf, 0x4d, 0x76, 0x94, 0x43, 0xa1, 0x9a, 0x78, 0xec, 0x0e, 0x35, 0xd7}},
|
||||||
|
{[16]byte{0x00, 0xa4, 0x55, 0xf1, 0xaa, 0x0e, 0xff, 0x5b, 0x49, 0xed, 0x1c, 0xb8, 0xe3, 0x47, 0xb6, 0x12}, [16]byte{0x00, 0x92, 0x39, 0xab, 0x72, 0xe0, 0x4b, 0xd9, 0xe4, 0x76, 0xdd, 0x4f, 0x96, 0x04, 0xaf, 0x3d}},
|
||||||
|
{[16]byte{0x00, 0xa5, 0x57, 0xf2, 0xae, 0x0b, 0xf9, 0x5c, 0x41, 0xe4, 0x16, 0xb3, 0xef, 0x4a, 0xb8, 0x1d}, [16]byte{0x00, 0x82, 0x19, 0x9b, 0x32, 0xb0, 0x2b, 0xa9, 0x64, 0xe6, 0x7d, 0xff, 0x56, 0xd4, 0x4f, 0xcd}},
|
||||||
|
{[16]byte{0x00, 0xa6, 0x51, 0xf7, 0xa2, 0x04, 0xf3, 0x55, 0x59, 0xff, 0x08, 0xae, 0xfb, 0x5d, 0xaa, 0x0c}, [16]byte{0x00, 0xb2, 0x79, 0xcb, 0xf2, 0x40, 0x8b, 0x39, 0xf9, 0x4b, 0x80, 0x32, 0x0b, 0xb9, 0x72, 0xc0}},
|
||||||
|
{[16]byte{0x00, 0xa7, 0x53, 0xf4, 0xa6, 0x01, 0xf5, 0x52, 0x51, 0xf6, 0x02, 0xa5, 0xf7, 0x50, 0xa4, 0x03}, [16]byte{0x00, 0xa2, 0x59, 0xfb, 0xb2, 0x10, 0xeb, 0x49, 0x79, 0xdb, 0x20, 0x82, 0xcb, 0x69, 0x92, 0x30}},
|
||||||
|
{[16]byte{0x00, 0xa8, 0x4d, 0xe5, 0x9a, 0x32, 0xd7, 0x7f, 0x29, 0x81, 0x64, 0xcc, 0xb3, 0x1b, 0xfe, 0x56}, [16]byte{0x00, 0x52, 0xa4, 0xf6, 0x55, 0x07, 0xf1, 0xa3, 0xaa, 0xf8, 0x0e, 0x5c, 0xff, 0xad, 0x5b, 0x09}},
|
||||||
|
{[16]byte{0x00, 0xa9, 0x4f, 0xe6, 0x9e, 0x37, 0xd1, 0x78, 0x21, 0x88, 0x6e, 0xc7, 0xbf, 0x16, 0xf0, 0x59}, [16]byte{0x00, 0x42, 0x84, 0xc6, 0x15, 0x57, 0x91, 0xd3, 0x2a, 0x68, 0xae, 0xec, 0x3f, 0x7d, 0xbb, 0xf9}},
|
||||||
|
{[16]byte{0x00, 0xaa, 0x49, 0xe3, 0x92, 0x38, 0xdb, 0x71, 0x39, 0x93, 0x70, 0xda, 0xab, 0x01, 0xe2, 0x48}, [16]byte{0x00, 0x72, 0xe4, 0x96, 0xd5, 0xa7, 0x31, 0x43, 0xb7, 0xc5, 0x53, 0x21, 0x62, 0x10, 0x86, 0xf4}},
|
||||||
|
{[16]byte{0x00, 0xab, 0x4b, 0xe0, 0x96, 0x3d, 0xdd, 0x76, 0x31, 0x9a, 0x7a, 0xd1, 0xa7, 0x0c, 0xec, 0x47}, [16]byte{0x00, 0x62, 0xc4, 0xa6, 0x95, 0xf7, 0x51, 0x33, 0x37, 0x55, 0xf3, 0x91, 0xa2, 0xc0, 0x66, 0x04}},
|
||||||
|
{[16]byte{0x00, 0xac, 0x45, 0xe9, 0x8a, 0x26, 0xcf, 0x63, 0x09, 0xa5, 0x4c, 0xe0, 0x83, 0x2f, 0xc6, 0x6a}, [16]byte{0x00, 0x12, 0x24, 0x36, 0x48, 0x5a, 0x6c, 0x7e, 0x90, 0x82, 0xb4, 0xa6, 0xd8, 0xca, 0xfc, 0xee}},
|
||||||
|
{[16]byte{0x00, 0xad, 0x47, 0xea, 0x8e, 0x23, 0xc9, 0x64, 0x01, 0xac, 0x46, 0xeb, 0x8f, 0x22, 0xc8, 0x65}, [16]byte{0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e}},
|
||||||
|
{[16]byte{0x00, 0xae, 0x41, 0xef, 0x82, 0x2c, 0xc3, 0x6d, 0x19, 0xb7, 0x58, 0xf6, 0x9b, 0x35, 0xda, 0x74}, [16]byte{0x00, 0x32, 0x64, 0x56, 0xc8, 0xfa, 0xac, 0x9e, 0x8d, 0xbf, 0xe9, 0xdb, 0x45, 0x77, 0x21, 0x13}},
|
||||||
|
{[16]byte{0x00, 0xaf, 0x43, 0xec, 0x86, 0x29, 0xc5, 0x6a, 0x11, 0xbe, 0x52, 0xfd, 0x97, 0x38, 0xd4, 0x7b}, [16]byte{0x00, 0x22, 0x44, 0x66, 0x88, 0xaa, 0xcc, 0xee, 0x0d, 0x2f, 0x49, 0x6b, 0x85, 0xa7, 0xc1, 0xe3}},
|
||||||
|
{[16]byte{0x00, 0xb0, 0x7d, 0xcd, 0xfa, 0x4a, 0x87, 0x37, 0xe9, 0x59, 0x94, 0x24, 0x13, 0xa3, 0x6e, 0xde}, [16]byte{0x00, 0xcf, 0x83, 0x4c, 0x1b, 0xd4, 0x98, 0x57, 0x36, 0xf9, 0xb5, 0x7a, 0x2d, 0xe2, 0xae, 0x61}},
|
||||||
|
{[16]byte{0x00, 0xb1, 0x7f, 0xce, 0xfe, 0x4f, 0x81, 0x30, 0xe1, 0x50, 0x9e, 0x2f, 0x1f, 0xae, 0x60, 0xd1}, [16]byte{0x00, 0xdf, 0xa3, 0x7c, 0x5b, 0x84, 0xf8, 0x27, 0xb6, 0x69, 0x15, 0xca, 0xed, 0x32, 0x4e, 0x91}},
|
||||||
|
{[16]byte{0x00, 0xb2, 0x79, 0xcb, 0xf2, 0x40, 0x8b, 0x39, 0xf9, 0x4b, 0x80, 0x32, 0x0b, 0xb9, 0x72, 0xc0}, [16]byte{0x00, 0xef, 0xc3, 0x2c, 0x9b, 0x74, 0x58, 0xb7, 0x2b, 0xc4, 0xe8, 0x07, 0xb0, 0x5f, 0x73, 0x9c}},
|
||||||
|
{[16]byte{0x00, 0xb3, 0x7b, 0xc8, 0xf6, 0x45, 0x8d, 0x3e, 0xf1, 0x42, 0x8a, 0x39, 0x07, 0xb4, 0x7c, 0xcf}, [16]byte{0x00, 0xff, 0xe3, 0x1c, 0xdb, 0x24, 0x38, 0xc7, 0xab, 0x54, 0x48, 0xb7, 0x70, 0x8f, 0x93, 0x6c}},
|
||||||
|
{[16]byte{0x00, 0xb4, 0x75, 0xc1, 0xea, 0x5e, 0x9f, 0x2b, 0xc9, 0x7d, 0xbc, 0x08, 0x23, 0x97, 0x56, 0xe2}, [16]byte{0x00, 0x8f, 0x03, 0x8c, 0x06, 0x89, 0x05, 0x8a, 0x0c, 0x83, 0x0f, 0x80, 0x0a, 0x85, 0x09, 0x86}},
|
||||||
|
{[16]byte{0x00, 0xb5, 0x77, 0xc2, 0xee, 0x5b, 0x99, 0x2c, 0xc1, 0x74, 0xb6, 0x03, 0x2f, 0x9a, 0x58, 0xed}, [16]byte{0x00, 0x9f, 0x23, 0xbc, 0x46, 0xd9, 0x65, 0xfa, 0x8c, 0x13, 0xaf, 0x30, 0xca, 0x55, 0xe9, 0x76}},
|
||||||
|
{[16]byte{0x00, 0xb6, 0x71, 0xc7, 0xe2, 0x54, 0x93, 0x25, 0xd9, 0x6f, 0xa8, 0x1e, 0x3b, 0x8d, 0x4a, 0xfc}, [16]byte{0x00, 0xaf, 0x43, 0xec, 0x86, 0x29, 0xc5, 0x6a, 0x11, 0xbe, 0x52, 0xfd, 0x97, 0x38, 0xd4, 0x7b}},
|
||||||
|
{[16]byte{0x00, 0xb7, 0x73, 0xc4, 0xe6, 0x51, 0x95, 0x22, 0xd1, 0x66, 0xa2, 0x15, 0x37, 0x80, 0x44, 0xf3}, [16]byte{0x00, 0xbf, 0x63, 0xdc, 0xc6, 0x79, 0xa5, 0x1a, 0x91, 0x2e, 0xf2, 0x4d, 0x57, 0xe8, 0x34, 0x8b}},
|
||||||
|
{[16]byte{0x00, 0xb8, 0x6d, 0xd5, 0xda, 0x62, 0xb7, 0x0f, 0xa9, 0x11, 0xc4, 0x7c, 0x73, 0xcb, 0x1e, 0xa6}, [16]byte{0x00, 0x4f, 0x9e, 0xd1, 0x21, 0x6e, 0xbf, 0xf0, 0x42, 0x0d, 0xdc, 0x93, 0x63, 0x2c, 0xfd, 0xb2}},
|
||||||
|
{[16]byte{0x00, 0xb9, 0x6f, 0xd6, 0xde, 0x67, 0xb1, 0x08, 0xa1, 0x18, 0xce, 0x77, 0x7f, 0xc6, 0x10, 0xa9}, [16]byte{0x00, 0x5f, 0xbe, 0xe1, 0x61, 0x3e, 0xdf, 0x80, 0xc2, 0x9d, 0x7c, 0x23, 0xa3, 0xfc, 0x1d, 0x42}},
|
||||||
|
{[16]byte{0x00, 0xba, 0x69, 0xd3, 0xd2, 0x68, 0xbb, 0x01, 0xb9, 0x03, 0xd0, 0x6a, 0x6b, 0xd1, 0x02, 0xb8}, [16]byte{0x00, 0x6f, 0xde, 0xb1, 0xa1, 0xce, 0x7f, 0x10, 0x5f, 0x30, 0x81, 0xee, 0xfe, 0x91, 0x20, 0x4f}},
|
||||||
|
{[16]byte{0x00, 0xbb, 0x6b, 0xd0, 0xd6, 0x6d, 0xbd, 0x06, 0xb1, 0x0a, 0xda, 0x61, 0x67, 0xdc, 0x0c, 0xb7}, [16]byte{0x00, 0x7f, 0xfe, 0x81, 0xe1, 0x9e, 0x1f, 0x60, 0xdf, 0xa0, 0x21, 0x5e, 0x3e, 0x41, 0xc0, 0xbf}},
|
||||||
|
{[16]byte{0x00, 0xbc, 0x65, 0xd9, 0xca, 0x76, 0xaf, 0x13, 0x89, 0x35, 0xec, 0x50, 0x43, 0xff, 0x26, 0x9a}, [16]byte{0x00, 0x0f, 0x1e, 0x11, 0x3c, 0x33, 0x22, 0x2d, 0x78, 0x77, 0x66, 0x69, 0x44, 0x4b, 0x5a, 0x55}},
|
||||||
|
{[16]byte{0x00, 0xbd, 0x67, 0xda, 0xce, 0x73, 0xa9, 0x14, 0x81, 0x3c, 0xe6, 0x5b, 0x4f, 0xf2, 0x28, 0x95}, [16]byte{0x00, 0x1f, 0x3e, 0x21, 0x7c, 0x63, 0x42, 0x5d, 0xf8, 0xe7, 0xc6, 0xd9, 0x84, 0x9b, 0xba, 0xa5}},
|
||||||
|
{[16]byte{0x00, 0xbe, 0x61, 0xdf, 0xc2, 0x7c, 0xa3, 0x1d, 0x99, 0x27, 0xf8, 0x46, 0x5b, 0xe5, 0x3a, 0x84}, [16]byte{0x00, 0x2f, 0x5e, 0x71, 0xbc, 0x93, 0xe2, 0xcd, 0x65, 0x4a, 0x3b, 0x14, 0xd9, 0xf6, 0x87, 0xa8}},
|
||||||
|
{[16]byte{0x00, 0xbf, 0x63, 0xdc, 0xc6, 0x79, 0xa5, 0x1a, 0x91, 0x2e, 0xf2, 0x4d, 0x57, 0xe8, 0x34, 0x8b}, [16]byte{0x00, 0x3f, 0x7e, 0x41, 0xfc, 0xc3, 0x82, 0xbd, 0xe5, 0xda, 0x9b, 0xa4, 0x19, 0x26, 0x67, 0x58}},
|
||||||
|
{[16]byte{0x00, 0xc0, 0x9d, 0x5d, 0x27, 0xe7, 0xba, 0x7a, 0x4e, 0x8e, 0xd3, 0x13, 0x69, 0xa9, 0xf4, 0x34}, [16]byte{0x00, 0x9c, 0x25, 0xb9, 0x4a, 0xd6, 0x6f, 0xf3, 0x94, 0x08, 0xb1, 0x2d, 0xde, 0x42, 0xfb, 0x67}},
|
||||||
|
{[16]byte{0x00, 0xc1, 0x9f, 0x5e, 0x23, 0xe2, 0xbc, 0x7d, 0x46, 0x87, 0xd9, 0x18, 0x65, 0xa4, 0xfa, 0x3b}, [16]byte{0x00, 0x8c, 0x05, 0x89, 0x0a, 0x86, 0x0f, 0x83, 0x14, 0x98, 0x11, 0x9d, 0x1e, 0x92, 0x1b, 0x97}},
|
||||||
|
{[16]byte{0x00, 0xc2, 0x99, 0x5b, 0x2f, 0xed, 0xb6, 0x74, 0x5e, 0x9c, 0xc7, 0x05, 0x71, 0xb3, 0xe8, 0x2a}, [16]byte{0x00, 0xbc, 0x65, 0xd9, 0xca, 0x76, 0xaf, 0x13, 0x89, 0x35, 0xec, 0x50, 0x43, 0xff, 0x26, 0x9a}},
|
||||||
|
{[16]byte{0x00, 0xc3, 0x9b, 0x58, 0x2b, 0xe8, 0xb0, 0x73, 0x56, 0x95, 0xcd, 0x0e, 0x7d, 0xbe, 0xe6, 0x25}, [16]byte{0x00, 0xac, 0x45, 0xe9, 0x8a, 0x26, 0xcf, 0x63, 0x09, 0xa5, 0x4c, 0xe0, 0x83, 0x2f, 0xc6, 0x6a}},
|
||||||
|
{[16]byte{0x00, 0xc4, 0x95, 0x51, 0x37, 0xf3, 0xa2, 0x66, 0x6e, 0xaa, 0xfb, 0x3f, 0x59, 0x9d, 0xcc, 0x08}, [16]byte{0x00, 0xdc, 0xa5, 0x79, 0x57, 0x8b, 0xf2, 0x2e, 0xae, 0x72, 0x0b, 0xd7, 0xf9, 0x25, 0x5c, 0x80}},
|
||||||
|
{[16]byte{0x00, 0xc5, 0x97, 0x52, 0x33, 0xf6, 0xa4, 0x61, 0x66, 0xa3, 0xf1, 0x34, 0x55, 0x90, 0xc2, 0x07}, [16]byte{0x00, 0xcc, 0x85, 0x49, 0x17, 0xdb, 0x92, 0x5e, 0x2e, 0xe2, 0xab, 0x67, 0x39, 0xf5, 0xbc, 0x70}},
|
||||||
|
{[16]byte{0x00, 0xc6, 0x91, 0x57, 0x3f, 0xf9, 0xae, 0x68, 0x7e, 0xb8, 0xef, 0x29, 0x41, 0x87, 0xd0, 0x16}, [16]byte{0x00, 0xfc, 0xe5, 0x19, 0xd7, 0x2b, 0x32, 0xce, 0xb3, 0x4f, 0x56, 0xaa, 0x64, 0x98, 0x81, 0x7d}},
|
||||||
|
{[16]byte{0x00, 0xc7, 0x93, 0x54, 0x3b, 0xfc, 0xa8, 0x6f, 0x76, 0xb1, 0xe5, 0x22, 0x4d, 0x8a, 0xde, 0x19}, [16]byte{0x00, 0xec, 0xc5, 0x29, 0x97, 0x7b, 0x52, 0xbe, 0x33, 0xdf, 0xf6, 0x1a, 0xa4, 0x48, 0x61, 0x8d}},
|
||||||
|
{[16]byte{0x00, 0xc8, 0x8d, 0x45, 0x07, 0xcf, 0x8a, 0x42, 0x0e, 0xc6, 0x83, 0x4b, 0x09, 0xc1, 0x84, 0x4c}, [16]byte{0x00, 0x1c, 0x38, 0x24, 0x70, 0x6c, 0x48, 0x54, 0xe0, 0xfc, 0xd8, 0xc4, 0x90, 0x8c, 0xa8, 0xb4}},
|
||||||
|
{[16]byte{0x00, 0xc9, 0x8f, 0x46, 0x03, 0xca, 0x8c, 0x45, 0x06, 0xcf, 0x89, 0x40, 0x05, 0xcc, 0x8a, 0x43}, [16]byte{0x00, 0x0c, 0x18, 0x14, 0x30, 0x3c, 0x28, 0x24, 0x60, 0x6c, 0x78, 0x74, 0x50, 0x5c, 0x48, 0x44}},
|
||||||
|
{[16]byte{0x00, 0xca, 0x89, 0x43, 0x0f, 0xc5, 0x86, 0x4c, 0x1e, 0xd4, 0x97, 0x5d, 0x11, 0xdb, 0x98, 0x52}, [16]byte{0x00, 0x3c, 0x78, 0x44, 0xf0, 0xcc, 0x88, 0xb4, 0xfd, 0xc1, 0x85, 0xb9, 0x0d, 0x31, 0x75, 0x49}},
|
||||||
|
{[16]byte{0x00, 0xcb, 0x8b, 0x40, 0x0b, 0xc0, 0x80, 0x4b, 0x16, 0xdd, 0x9d, 0x56, 0x1d, 0xd6, 0x96, 0x5d}, [16]byte{0x00, 0x2c, 0x58, 0x74, 0xb0, 0x9c, 0xe8, 0xc4, 0x7d, 0x51, 0x25, 0x09, 0xcd, 0xe1, 0x95, 0xb9}},
|
||||||
|
{[16]byte{0x00, 0xcc, 0x85, 0x49, 0x17, 0xdb, 0x92, 0x5e, 0x2e, 0xe2, 0xab, 0x67, 0x39, 0xf5, 0xbc, 0x70}, [16]byte{0x00, 0x5c, 0xb8, 0xe4, 0x6d, 0x31, 0xd5, 0x89, 0xda, 0x86, 0x62, 0x3e, 0xb7, 0xeb, 0x0f, 0x53}},
|
||||||
|
{[16]byte{0x00, 0xcd, 0x87, 0x4a, 0x13, 0xde, 0x94, 0x59, 0x26, 0xeb, 0xa1, 0x6c, 0x35, 0xf8, 0xb2, 0x7f}, [16]byte{0x00, 0x4c, 0x98, 0xd4, 0x2d, 0x61, 0xb5, 0xf9, 0x5a, 0x16, 0xc2, 0x8e, 0x77, 0x3b, 0xef, 0xa3}},
|
||||||
|
{[16]byte{0x00, 0xce, 0x81, 0x4f, 0x1f, 0xd1, 0x9e, 0x50, 0x3e, 0xf0, 0xbf, 0x71, 0x21, 0xef, 0xa0, 0x6e}, [16]byte{0x00, 0x7c, 0xf8, 0x84, 0xed, 0x91, 0x15, 0x69, 0xc7, 0xbb, 0x3f, 0x43, 0x2a, 0x56, 0xd2, 0xae}},
|
||||||
|
{[16]byte{0x00, 0xcf, 0x83, 0x4c, 0x1b, 0xd4, 0x98, 0x57, 0x36, 0xf9, 0xb5, 0x7a, 0x2d, 0xe2, 0xae, 0x61}, [16]byte{0x00, 0x6c, 0xd8, 0xb4, 0xad, 0xc1, 0x75, 0x19, 0x47, 0x2b, 0x9f, 0xf3, 0xea, 0x86, 0x32, 0x5e}},
|
||||||
|
{[16]byte{0x00, 0xd0, 0xbd, 0x6d, 0x67, 0xb7, 0xda, 0x0a, 0xce, 0x1e, 0x73, 0xa3, 0xa9, 0x79, 0x14, 0xc4}, [16]byte{0x00, 0x81, 0x1f, 0x9e, 0x3e, 0xbf, 0x21, 0xa0, 0x7c, 0xfd, 0x63, 0xe2, 0x42, 0xc3, 0x5d, 0xdc}},
|
||||||
|
{[16]byte{0x00, 0xd1, 0xbf, 0x6e, 0x63, 0xb2, 0xdc, 0x0d, 0xc6, 0x17, 0x79, 0xa8, 0xa5, 0x74, 0x1a, 0xcb}, [16]byte{0x00, 0x91, 0x3f, 0xae, 0x7e, 0xef, 0x41, 0xd0, 0xfc, 0x6d, 0xc3, 0x52, 0x82, 0x13, 0xbd, 0x2c}},
|
||||||
|
{[16]byte{0x00, 0xd2, 0xb9, 0x6b, 0x6f, 0xbd, 0xd6, 0x04, 0xde, 0x0c, 0x67, 0xb5, 0xb1, 0x63, 0x08, 0xda}, [16]byte{0x00, 0xa1, 0x5f, 0xfe, 0xbe, 0x1f, 0xe1, 0x40, 0x61, 0xc0, 0x3e, 0x9f, 0xdf, 0x7e, 0x80, 0x21}},
|
||||||
|
{[16]byte{0x00, 0xd3, 0xbb, 0x68, 0x6b, 0xb8, 0xd0, 0x03, 0xd6, 0x05, 0x6d, 0xbe, 0xbd, 0x6e, 0x06, 0xd5}, [16]byte{0x00, 0xb1, 0x7f, 0xce, 0xfe, 0x4f, 0x81, 0x30, 0xe1, 0x50, 0x9e, 0x2f, 0x1f, 0xae, 0x60, 0xd1}},
|
||||||
|
{[16]byte{0x00, 0xd4, 0xb5, 0x61, 0x77, 0xa3, 0xc2, 0x16, 0xee, 0x3a, 0x5b, 0x8f, 0x99, 0x4d, 0x2c, 0xf8}, [16]byte{0x00, 0xc1, 0x9f, 0x5e, 0x23, 0xe2, 0xbc, 0x7d, 0x46, 0x87, 0xd9, 0x18, 0x65, 0xa4, 0xfa, 0x3b}},
|
||||||
|
{[16]byte{0x00, 0xd5, 0xb7, 0x62, 0x73, 0xa6, 0xc4, 0x11, 0xe6, 0x33, 0x51, 0x84, 0x95, 0x40, 0x22, 0xf7}, [16]byte{0x00, 0xd1, 0xbf, 0x6e, 0x63, 0xb2, 0xdc, 0x0d, 0xc6, 0x17, 0x79, 0xa8, 0xa5, 0x74, 0x1a, 0xcb}},
|
||||||
|
{[16]byte{0x00, 0xd6, 0xb1, 0x67, 0x7f, 0xa9, 0xce, 0x18, 0xfe, 0x28, 0x4f, 0x99, 0x81, 0x57, 0x30, 0xe6}, [16]byte{0x00, 0xe1, 0xdf, 0x3e, 0xa3, 0x42, 0x7c, 0x9d, 0x5b, 0xba, 0x84, 0x65, 0xf8, 0x19, 0x27, 0xc6}},
|
||||||
|
{[16]byte{0x00, 0xd7, 0xb3, 0x64, 0x7b, 0xac, 0xc8, 0x1f, 0xf6, 0x21, 0x45, 0x92, 0x8d, 0x5a, 0x3e, 0xe9}, [16]byte{0x00, 0xf1, 0xff, 0x0e, 0xe3, 0x12, 0x1c, 0xed, 0xdb, 0x2a, 0x24, 0xd5, 0x38, 0xc9, 0xc7, 0x36}},
|
||||||
|
{[16]byte{0x00, 0xd8, 0xad, 0x75, 0x47, 0x9f, 0xea, 0x32, 0x8e, 0x56, 0x23, 0xfb, 0xc9, 0x11, 0x64, 0xbc}, [16]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}},
|
||||||
|
{[16]byte{0x00, 0xd9, 0xaf, 0x76, 0x43, 0x9a, 0xec, 0x35, 0x86, 0x5f, 0x29, 0xf0, 0xc5, 0x1c, 0x6a, 0xb3}, [16]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
|
||||||
|
{[16]byte{0x00, 0xda, 0xa9, 0x73, 0x4f, 0x95, 0xe6, 0x3c, 0x9e, 0x44, 0x37, 0xed, 0xd1, 0x0b, 0x78, 0xa2}, [16]byte{0x00, 0x21, 0x42, 0x63, 0x84, 0xa5, 0xc6, 0xe7, 0x15, 0x34, 0x57, 0x76, 0x91, 0xb0, 0xd3, 0xf2}},
|
||||||
|
{[16]byte{0x00, 0xdb, 0xab, 0x70, 0x4b, 0x90, 0xe0, 0x3b, 0x96, 0x4d, 0x3d, 0xe6, 0xdd, 0x06, 0x76, 0xad}, [16]byte{0x00, 0x31, 0x62, 0x53, 0xc4, 0xf5, 0xa6, 0x97, 0x95, 0xa4, 0xf7, 0xc6, 0x51, 0x60, 0x33, 0x02}},
|
||||||
|
{[16]byte{0x00, 0xdc, 0xa5, 0x79, 0x57, 0x8b, 0xf2, 0x2e, 0xae, 0x72, 0x0b, 0xd7, 0xf9, 0x25, 0x5c, 0x80}, [16]byte{0x00, 0x41, 0x82, 0xc3, 0x19, 0x58, 0x9b, 0xda, 0x32, 0x73, 0xb0, 0xf1, 0x2b, 0x6a, 0xa9, 0xe8}},
|
||||||
|
{[16]byte{0x00, 0xdd, 0xa7, 0x7a, 0x53, 0x8e, 0xf4, 0x29, 0xa6, 0x7b, 0x01, 0xdc, 0xf5, 0x28, 0x52, 0x8f}, [16]byte{0x00, 0x51, 0xa2, 0xf3, 0x59, 0x08, 0xfb, 0xaa, 0xb2, 0xe3, 0x10, 0x41, 0xeb, 0xba, 0x49, 0x18}},
|
||||||
|
{[16]byte{0x00, 0xde, 0xa1, 0x7f, 0x5f, 0x81, 0xfe, 0x20, 0xbe, 0x60, 0x1f, 0xc1, 0xe1, 0x3f, 0x40, 0x9e}, [16]byte{0x00, 0x61, 0xc2, 0xa3, 0x99, 0xf8, 0x5b, 0x3a, 0x2f, 0x4e, 0xed, 0x8c, 0xb6, 0xd7, 0x74, 0x15}},
|
||||||
|
{[16]byte{0x00, 0xdf, 0xa3, 0x7c, 0x5b, 0x84, 0xf8, 0x27, 0xb6, 0x69, 0x15, 0xca, 0xed, 0x32, 0x4e, 0x91}, [16]byte{0x00, 0x71, 0xe2, 0x93, 0xd9, 0xa8, 0x3b, 0x4a, 0xaf, 0xde, 0x4d, 0x3c, 0x76, 0x07, 0x94, 0xe5}},
|
||||||
|
{[16]byte{0x00, 0xe0, 0xdd, 0x3d, 0xa7, 0x47, 0x7a, 0x9a, 0x53, 0xb3, 0x8e, 0x6e, 0xf4, 0x14, 0x29, 0xc9}, [16]byte{0x00, 0xa6, 0x51, 0xf7, 0xa2, 0x04, 0xf3, 0x55, 0x59, 0xff, 0x08, 0xae, 0xfb, 0x5d, 0xaa, 0x0c}},
|
||||||
|
{[16]byte{0x00, 0xe1, 0xdf, 0x3e, 0xa3, 0x42, 0x7c, 0x9d, 0x5b, 0xba, 0x84, 0x65, 0xf8, 0x19, 0x27, 0xc6}, [16]byte{0x00, 0xb6, 0x71, 0xc7, 0xe2, 0x54, 0x93, 0x25, 0xd9, 0x6f, 0xa8, 0x1e, 0x3b, 0x8d, 0x4a, 0xfc}},
|
||||||
|
{[16]byte{0x00, 0xe2, 0xd9, 0x3b, 0xaf, 0x4d, 0x76, 0x94, 0x43, 0xa1, 0x9a, 0x78, 0xec, 0x0e, 0x35, 0xd7}, [16]byte{0x00, 0x86, 0x11, 0x97, 0x22, 0xa4, 0x33, 0xb5, 0x44, 0xc2, 0x55, 0xd3, 0x66, 0xe0, 0x77, 0xf1}},
|
||||||
|
{[16]byte{0x00, 0xe3, 0xdb, 0x38, 0xab, 0x48, 0x70, 0x93, 0x4b, 0xa8, 0x90, 0x73, 0xe0, 0x03, 0x3b, 0xd8}, [16]byte{0x00, 0x96, 0x31, 0xa7, 0x62, 0xf4, 0x53, 0xc5, 0xc4, 0x52, 0xf5, 0x63, 0xa6, 0x30, 0x97, 0x01}},
|
||||||
|
{[16]byte{0x00, 0xe4, 0xd5, 0x31, 0xb7, 0x53, 0x62, 0x86, 0x73, 0x97, 0xa6, 0x42, 0xc4, 0x20, 0x11, 0xf5}, [16]byte{0x00, 0xe6, 0xd1, 0x37, 0xbf, 0x59, 0x6e, 0x88, 0x63, 0x85, 0xb2, 0x54, 0xdc, 0x3a, 0x0d, 0xeb}},
|
||||||
|
{[16]byte{0x00, 0xe5, 0xd7, 0x32, 0xb3, 0x56, 0x64, 0x81, 0x7b, 0x9e, 0xac, 0x49, 0xc8, 0x2d, 0x1f, 0xfa}, [16]byte{0x00, 0xf6, 0xf1, 0x07, 0xff, 0x09, 0x0e, 0xf8, 0xe3, 0x15, 0x12, 0xe4, 0x1c, 0xea, 0xed, 0x1b}},
|
||||||
|
{[16]byte{0x00, 0xe6, 0xd1, 0x37, 0xbf, 0x59, 0x6e, 0x88, 0x63, 0x85, 0xb2, 0x54, 0xdc, 0x3a, 0x0d, 0xeb}, [16]byte{0x00, 0xc6, 0x91, 0x57, 0x3f, 0xf9, 0xae, 0x68, 0x7e, 0xb8, 0xef, 0x29, 0x41, 0x87, 0xd0, 0x16}},
|
||||||
|
{[16]byte{0x00, 0xe7, 0xd3, 0x34, 0xbb, 0x5c, 0x68, 0x8f, 0x6b, 0x8c, 0xb8, 0x5f, 0xd0, 0x37, 0x03, 0xe4}, [16]byte{0x00, 0xd6, 0xb1, 0x67, 0x7f, 0xa9, 0xce, 0x18, 0xfe, 0x28, 0x4f, 0x99, 0x81, 0x57, 0x30, 0xe6}},
|
||||||
|
{[16]byte{0x00, 0xe8, 0xcd, 0x25, 0x87, 0x6f, 0x4a, 0xa2, 0x13, 0xfb, 0xde, 0x36, 0x94, 0x7c, 0x59, 0xb1}, [16]byte{0x00, 0x26, 0x4c, 0x6a, 0x98, 0xbe, 0xd4, 0xf2, 0x2d, 0x0b, 0x61, 0x47, 0xb5, 0x93, 0xf9, 0xdf}},
|
||||||
|
{[16]byte{0x00, 0xe9, 0xcf, 0x26, 0x83, 0x6a, 0x4c, 0xa5, 0x1b, 0xf2, 0xd4, 0x3d, 0x98, 0x71, 0x57, 0xbe}, [16]byte{0x00, 0x36, 0x6c, 0x5a, 0xd8, 0xee, 0xb4, 0x82, 0xad, 0x9b, 0xc1, 0xf7, 0x75, 0x43, 0x19, 0x2f}},
|
||||||
|
{[16]byte{0x00, 0xea, 0xc9, 0x23, 0x8f, 0x65, 0x46, 0xac, 0x03, 0xe9, 0xca, 0x20, 0x8c, 0x66, 0x45, 0xaf}, [16]byte{0x00, 0x06, 0x0c, 0x0a, 0x18, 0x1e, 0x14, 0x12, 0x30, 0x36, 0x3c, 0x3a, 0x28, 0x2e, 0x24, 0x22}},
|
||||||
|
{[16]byte{0x00, 0xeb, 0xcb, 0x20, 0x8b, 0x60, 0x40, 0xab, 0x0b, 0xe0, 0xc0, 0x2b, 0x80, 0x6b, 0x4b, 0xa0}, [16]byte{0x00, 0x16, 0x2c, 0x3a, 0x58, 0x4e, 0x74, 0x62, 0xb0, 0xa6, 0x9c, 0x8a, 0xe8, 0xfe, 0xc4, 0xd2}},
|
||||||
|
{[16]byte{0x00, 0xec, 0xc5, 0x29, 0x97, 0x7b, 0x52, 0xbe, 0x33, 0xdf, 0xf6, 0x1a, 0xa4, 0x48, 0x61, 0x8d}, [16]byte{0x00, 0x66, 0xcc, 0xaa, 0x85, 0xe3, 0x49, 0x2f, 0x17, 0x71, 0xdb, 0xbd, 0x92, 0xf4, 0x5e, 0x38}},
|
||||||
|
{[16]byte{0x00, 0xed, 0xc7, 0x2a, 0x93, 0x7e, 0x54, 0xb9, 0x3b, 0xd6, 0xfc, 0x11, 0xa8, 0x45, 0x6f, 0x82}, [16]byte{0x00, 0x76, 0xec, 0x9a, 0xc5, 0xb3, 0x29, 0x5f, 0x97, 0xe1, 0x7b, 0x0d, 0x52, 0x24, 0xbe, 0xc8}},
|
||||||
|
{[16]byte{0x00, 0xee, 0xc1, 0x2f, 0x9f, 0x71, 0x5e, 0xb0, 0x23, 0xcd, 0xe2, 0x0c, 0xbc, 0x52, 0x7d, 0x93}, [16]byte{0x00, 0x46, 0x8c, 0xca, 0x05, 0x43, 0x89, 0xcf, 0x0a, 0x4c, 0x86, 0xc0, 0x0f, 0x49, 0x83, 0xc5}},
|
||||||
|
{[16]byte{0x00, 0xef, 0xc3, 0x2c, 0x9b, 0x74, 0x58, 0xb7, 0x2b, 0xc4, 0xe8, 0x07, 0xb0, 0x5f, 0x73, 0x9c}, [16]byte{0x00, 0x56, 0xac, 0xfa, 0x45, 0x13, 0xe9, 0xbf, 0x8a, 0xdc, 0x26, 0x70, 0xcf, 0x99, 0x63, 0x35}},
|
||||||
|
{[16]byte{0x00, 0xf0, 0xfd, 0x0d, 0xe7, 0x17, 0x1a, 0xea, 0xd3, 0x23, 0x2e, 0xde, 0x34, 0xc4, 0xc9, 0x39}, [16]byte{0x00, 0xbb, 0x6b, 0xd0, 0xd6, 0x6d, 0xbd, 0x06, 0xb1, 0x0a, 0xda, 0x61, 0x67, 0xdc, 0x0c, 0xb7}},
|
||||||
|
{[16]byte{0x00, 0xf1, 0xff, 0x0e, 0xe3, 0x12, 0x1c, 0xed, 0xdb, 0x2a, 0x24, 0xd5, 0x38, 0xc9, 0xc7, 0x36}, [16]byte{0x00, 0xab, 0x4b, 0xe0, 0x96, 0x3d, 0xdd, 0x76, 0x31, 0x9a, 0x7a, 0xd1, 0xa7, 0x0c, 0xec, 0x47}},
|
||||||
|
{[16]byte{0x00, 0xf2, 0xf9, 0x0b, 0xef, 0x1d, 0x16, 0xe4, 0xc3, 0x31, 0x3a, 0xc8, 0x2c, 0xde, 0xd5, 0x27}, [16]byte{0x00, 0x9b, 0x2b, 0xb0, 0x56, 0xcd, 0x7d, 0xe6, 0xac, 0x37, 0x87, 0x1c, 0xfa, 0x61, 0xd1, 0x4a}},
|
||||||
|
{[16]byte{0x00, 0xf3, 0xfb, 0x08, 0xeb, 0x18, 0x10, 0xe3, 0xcb, 0x38, 0x30, 0xc3, 0x20, 0xd3, 0xdb, 0x28}, [16]byte{0x00, 0x8b, 0x0b, 0x80, 0x16, 0x9d, 0x1d, 0x96, 0x2c, 0xa7, 0x27, 0xac, 0x3a, 0xb1, 0x31, 0xba}},
|
||||||
|
{[16]byte{0x00, 0xf4, 0xf5, 0x01, 0xf7, 0x03, 0x02, 0xf6, 0xf3, 0x07, 0x06, 0xf2, 0x04, 0xf0, 0xf1, 0x05}, [16]byte{0x00, 0xfb, 0xeb, 0x10, 0xcb, 0x30, 0x20, 0xdb, 0x8b, 0x70, 0x60, 0x9b, 0x40, 0xbb, 0xab, 0x50}},
|
||||||
|
{[16]byte{0x00, 0xf5, 0xf7, 0x02, 0xf3, 0x06, 0x04, 0xf1, 0xfb, 0x0e, 0x0c, 0xf9, 0x08, 0xfd, 0xff, 0x0a}, [16]byte{0x00, 0xeb, 0xcb, 0x20, 0x8b, 0x60, 0x40, 0xab, 0x0b, 0xe0, 0xc0, 0x2b, 0x80, 0x6b, 0x4b, 0xa0}},
|
||||||
|
{[16]byte{0x00, 0xf6, 0xf1, 0x07, 0xff, 0x09, 0x0e, 0xf8, 0xe3, 0x15, 0x12, 0xe4, 0x1c, 0xea, 0xed, 0x1b}, [16]byte{0x00, 0xdb, 0xab, 0x70, 0x4b, 0x90, 0xe0, 0x3b, 0x96, 0x4d, 0x3d, 0xe6, 0xdd, 0x06, 0x76, 0xad}},
|
||||||
|
{[16]byte{0x00, 0xf7, 0xf3, 0x04, 0xfb, 0x0c, 0x08, 0xff, 0xeb, 0x1c, 0x18, 0xef, 0x10, 0xe7, 0xe3, 0x14}, [16]byte{0x00, 0xcb, 0x8b, 0x40, 0x0b, 0xc0, 0x80, 0x4b, 0x16, 0xdd, 0x9d, 0x56, 0x1d, 0xd6, 0x96, 0x5d}},
|
||||||
|
{[16]byte{0x00, 0xf8, 0xed, 0x15, 0xc7, 0x3f, 0x2a, 0xd2, 0x93, 0x6b, 0x7e, 0x86, 0x54, 0xac, 0xb9, 0x41}, [16]byte{0x00, 0x3b, 0x76, 0x4d, 0xec, 0xd7, 0x9a, 0xa1, 0xc5, 0xfe, 0xb3, 0x88, 0x29, 0x12, 0x5f, 0x64}},
|
||||||
|
{[16]byte{0x00, 0xf9, 0xef, 0x16, 0xc3, 0x3a, 0x2c, 0xd5, 0x9b, 0x62, 0x74, 0x8d, 0x58, 0xa1, 0xb7, 0x4e}, [16]byte{0x00, 0x2b, 0x56, 0x7d, 0xac, 0x87, 0xfa, 0xd1, 0x45, 0x6e, 0x13, 0x38, 0xe9, 0xc2, 0xbf, 0x94}},
|
||||||
|
{[16]byte{0x00, 0xfa, 0xe9, 0x13, 0xcf, 0x35, 0x26, 0xdc, 0x83, 0x79, 0x6a, 0x90, 0x4c, 0xb6, 0xa5, 0x5f}, [16]byte{0x00, 0x1b, 0x36, 0x2d, 0x6c, 0x77, 0x5a, 0x41, 0xd8, 0xc3, 0xee, 0xf5, 0xb4, 0xaf, 0x82, 0x99}},
|
||||||
|
{[16]byte{0x00, 0xfb, 0xeb, 0x10, 0xcb, 0x30, 0x20, 0xdb, 0x8b, 0x70, 0x60, 0x9b, 0x40, 0xbb, 0xab, 0x50}, [16]byte{0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69}},
|
||||||
|
{[16]byte{0x00, 0xfc, 0xe5, 0x19, 0xd7, 0x2b, 0x32, 0xce, 0xb3, 0x4f, 0x56, 0xaa, 0x64, 0x98, 0x81, 0x7d}, [16]byte{0x00, 0x7b, 0xf6, 0x8d, 0xf1, 0x8a, 0x07, 0x7c, 0xff, 0x84, 0x09, 0x72, 0x0e, 0x75, 0xf8, 0x83}},
|
||||||
|
{[16]byte{0x00, 0xfd, 0xe7, 0x1a, 0xd3, 0x2e, 0x34, 0xc9, 0xbb, 0x46, 0x5c, 0xa1, 0x68, 0x95, 0x8f, 0x72}, [16]byte{0x00, 0x6b, 0xd6, 0xbd, 0xb1, 0xda, 0x67, 0x0c, 0x7f, 0x14, 0xa9, 0xc2, 0xce, 0xa5, 0x18, 0x73}},
|
||||||
|
{[16]byte{0x00, 0xfe, 0xe1, 0x1f, 0xdf, 0x21, 0x3e, 0xc0, 0xa3, 0x5d, 0x42, 0xbc, 0x7c, 0x82, 0x9d, 0x63}, [16]byte{0x00, 0x5b, 0xb6, 0xed, 0x71, 0x2a, 0xc7, 0x9c, 0xe2, 0xb9, 0x54, 0x0f, 0x93, 0xc8, 0x25, 0x7e}},
|
||||||
|
{[16]byte{0x00, 0xff, 0xe3, 0x1c, 0xdb, 0x24, 0x38, 0xc7, 0xab, 0x54, 0x48, 0xb7, 0x70, 0x8f, 0x93, 0x6c}, [16]byte{0x00, 0x4b, 0x96, 0xdd, 0x31, 0x7a, 0xa7, 0xec, 0x62, 0x29, 0xf4, 0xbf, 0x53, 0x18, 0xc5, 0x8e}},
|
||||||
|
}
|
246
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/berlekamp_welch.go
generated
vendored
Normal file
246
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/berlekamp_welch.go
generated
vendored
Normal file
|
@ -0,0 +1,246 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2016-2017 Vivint, Inc.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package infectious
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Decode will take a destination buffer (can be nil) and a list of shares
|
||||||
|
// (pieces). It will return the data passed in to the corresponding Encode
|
||||||
|
// call or return an error.
|
||||||
|
//
|
||||||
|
// It will first correct the shares using Correct, mutating and reordering the
|
||||||
|
// passed-in shares arguments. Then it will rebuild the data using Rebuild.
|
||||||
|
// Finally it will concatenate the data into the given output buffer dst if it
|
||||||
|
// has capacity, growing it otherwise.
|
||||||
|
//
|
||||||
|
// If you already know your data does not contain errors, Rebuild will be
|
||||||
|
// faster.
|
||||||
|
//
|
||||||
|
// If you only want to identify which pieces are bad, you may be interested in
|
||||||
|
// Correct.
|
||||||
|
//
|
||||||
|
// If you don't want the data concatenated for you, you can use Correct and
|
||||||
|
// then Rebuild individually.
|
||||||
|
func (f *FEC) Decode(dst []byte, shares []Share) ([]byte, error) {
|
||||||
|
err := f.Correct(shares)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(shares) == 0 {
|
||||||
|
return nil, errors.New("must specify at least one share")
|
||||||
|
}
|
||||||
|
piece_len := len(shares[0].Data)
|
||||||
|
result_len := piece_len * f.k
|
||||||
|
if cap(dst) < result_len {
|
||||||
|
dst = make([]byte, result_len)
|
||||||
|
} else {
|
||||||
|
dst = dst[:result_len]
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst, f.Rebuild(shares, func(s Share) {
|
||||||
|
copy(dst[s.Number*piece_len:], s.Data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FEC) decode(shares []Share, output func(Share)) error {
|
||||||
|
err := f.Correct(shares)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return f.Rebuild(shares, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Correct implements the Berlekamp-Welch algorithm for correcting
|
||||||
|
// errors in given FEC encoded data. It will correct the supplied shares,
|
||||||
|
// mutating the underlying byte slices and reordering the shares
|
||||||
|
func (fc *FEC) Correct(shares []Share) error {
|
||||||
|
if len(shares) < fc.k {
|
||||||
|
return errors.New("must specify at least the number of required shares")
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(byNumber(shares))
|
||||||
|
|
||||||
|
// fast path: check to see if there are no errors by evaluating it with
|
||||||
|
// the syndrome matrix.
|
||||||
|
synd, err := fc.syndromeMatrix(shares)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
buf := make([]byte, len(shares[0].Data))
|
||||||
|
|
||||||
|
for i := 0; i < synd.r; i++ {
|
||||||
|
for j := range buf {
|
||||||
|
buf[j] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := 0; j < synd.c; j++ {
|
||||||
|
addmul(buf, shares[j].Data, byte(synd.get(i, j)))
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := range buf {
|
||||||
|
if buf[j] == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
data, err := fc.berlekampWelch(shares, j)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, share := range shares {
|
||||||
|
share.Data[j] = data[share.Number]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fc *FEC) berlekampWelch(shares []Share, index int) ([]byte, error) {
|
||||||
|
k := fc.k // required size
|
||||||
|
r := len(shares) // required + redundancy size
|
||||||
|
e := (r - k) / 2 // deg of E polynomial
|
||||||
|
q := e + k // def of Q polynomial
|
||||||
|
|
||||||
|
if e <= 0 {
|
||||||
|
return nil, NotEnoughShares
|
||||||
|
}
|
||||||
|
|
||||||
|
const interp_base = gfVal(2)
|
||||||
|
|
||||||
|
eval_point := func(num int) gfVal {
|
||||||
|
if num == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return interp_base.pow(num - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
dim := q + e
|
||||||
|
|
||||||
|
// build the system of equations s * u = f
|
||||||
|
s := matrixNew(dim, dim) // constraint matrix
|
||||||
|
a := matrixNew(dim, dim) // augmented matrix
|
||||||
|
f := make(gfVals, dim) // constant column vector
|
||||||
|
u := make(gfVals, dim) // solution vector
|
||||||
|
|
||||||
|
for i := 0; i < dim; i++ {
|
||||||
|
x_i := eval_point(shares[i].Number)
|
||||||
|
r_i := gfConst(shares[i].Data[index])
|
||||||
|
|
||||||
|
f[i] = x_i.pow(e).mul(r_i)
|
||||||
|
|
||||||
|
for j := 0; j < q; j++ {
|
||||||
|
s.set(i, j, x_i.pow(j))
|
||||||
|
if i == j {
|
||||||
|
a.set(i, j, gfConst(1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for k := 0; k < e; k++ {
|
||||||
|
j := k + q
|
||||||
|
|
||||||
|
s.set(i, j, x_i.pow(k).mul(r_i))
|
||||||
|
if i == j {
|
||||||
|
a.set(i, j, gfConst(1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// invert and put the result in a
|
||||||
|
err := s.invertWith(a)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiply the inverted matrix by the column vector
|
||||||
|
for i := 0; i < dim; i++ {
|
||||||
|
ri := a.indexRow(i)
|
||||||
|
u[i] = ri.dot(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// reverse u for easier construction of the polynomials
|
||||||
|
for i := 0; i < len(u)/2; i++ {
|
||||||
|
o := len(u) - i - 1
|
||||||
|
u[i], u[o] = u[o], u[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
q_poly := gfPoly(u[e:])
|
||||||
|
e_poly := append(gfPoly{gfConst(1)}, u[:e]...)
|
||||||
|
|
||||||
|
p_poly, rem, err := q_poly.div(e_poly)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !rem.isZero() {
|
||||||
|
return nil, TooManyErrors
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]byte, fc.n)
|
||||||
|
for i := range out {
|
||||||
|
pt := gfConst(0)
|
||||||
|
if i != 0 {
|
||||||
|
pt = interp_base.pow(i - 1)
|
||||||
|
}
|
||||||
|
out[i] = byte(p_poly.eval(pt))
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fc *FEC) syndromeMatrix(shares []Share) (gfMat, error) {
|
||||||
|
// get a list of keepers
|
||||||
|
keepers := make([]bool, fc.n)
|
||||||
|
shareCount := 0
|
||||||
|
for _, share := range shares {
|
||||||
|
if !keepers[share.Number] {
|
||||||
|
keepers[share.Number] = true
|
||||||
|
shareCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a vandermonde matrix but skip columns where we're missing the
|
||||||
|
// share.
|
||||||
|
out := matrixNew(fc.k, shareCount)
|
||||||
|
for i := 0; i < fc.k; i++ {
|
||||||
|
skipped := 0
|
||||||
|
for j := 0; j < fc.n; j++ {
|
||||||
|
if !keepers[j] {
|
||||||
|
skipped++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
out.set(i, j-skipped, gfConst(fc.vand_matrix[i*fc.n+j]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// standardize the output and convert into parity form
|
||||||
|
err := out.standardize()
|
||||||
|
if err != nil {
|
||||||
|
return gfMat{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.parity(), nil
|
||||||
|
}
|
50
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/common.go
generated
vendored
Normal file
50
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/common.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2016-2017 Vivint, Inc.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
// Package infectious implements Reed-Solomon forward error correction [1]. It
|
||||||
|
// uses the Berlekamp-Welch [2] error correction algorithm to achieve the
|
||||||
|
// ability to actually correct errors.
|
||||||
|
//
|
||||||
|
// Caution: this package API leans toward providing the user more power and
|
||||||
|
// performance at the expense of having some really sharp edges! Read the
|
||||||
|
// documentation about memory lifecycles carefully!
|
||||||
|
//
|
||||||
|
// We wrote a blog post about how this library works!
|
||||||
|
// https://innovation.vivint.com/introduction-to-reed-solomon-bc264d0794f8
|
||||||
|
//
|
||||||
|
// [1] https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction
|
||||||
|
// [2] https://en.wikipedia.org/wiki/Berlekamp%E2%80%93Welch_algorithm
|
||||||
|
package infectious
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"golang.org/x/sys/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
var hasAVX2 = cpu.X86.HasAVX2
|
||||||
|
var hasSSSE3 = cpu.X86.HasSSSE3
|
||||||
|
|
||||||
|
var (
|
||||||
|
NotEnoughShares = errors.New("not enough shares")
|
||||||
|
TooManyErrors = errors.New("too many errors to reconstruct")
|
||||||
|
)
|
|
@ -0,0 +1,323 @@
|
||||||
|
// (C) 1996-1998 Luigi Rizzo (luigi@iet.unipi.it)
|
||||||
|
// 2009-2010 Jack Lloyd (lloyd@randombit.net)
|
||||||
|
// 2011 Billy Brumley (billy.brumley@aalto.fi)
|
||||||
|
// 2016-2017 Vivint, Inc. (jeff.wendling@vivint.com)
|
||||||
|
//
|
||||||
|
// Portions derived from code by Phil Karn (karn@ka9q.ampr.org),
|
||||||
|
// Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari
|
||||||
|
// Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package infectious
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FEC represents operations performed on a Reed-Solomon-based
|
||||||
|
// forward error correction code. Make sure to construct using NewFEC.
|
||||||
|
type FEC struct {
|
||||||
|
k int
|
||||||
|
n int
|
||||||
|
enc_matrix []byte
|
||||||
|
vand_matrix []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFEC creates a *FEC using k required pieces and n total pieces.
|
||||||
|
// Encoding data with this *FEC will generate n pieces, and decoding
|
||||||
|
// data requires k uncorrupted pieces. If during decode more than k pieces
|
||||||
|
// exist, corrupted data can be detected and recovered from.
|
||||||
|
func NewFEC(k, n int) (*FEC, error) {
|
||||||
|
if k <= 0 || n <= 0 || k > 256 || n > 256 || k > n {
|
||||||
|
return nil, errors.New("requires 1 <= k <= n <= 256")
|
||||||
|
}
|
||||||
|
|
||||||
|
enc_matrix := make([]byte, n*k)
|
||||||
|
temp_matrix := make([]byte, n*k)
|
||||||
|
createInvertedVdm(temp_matrix, k)
|
||||||
|
|
||||||
|
for i := k * k; i < len(temp_matrix); i++ {
|
||||||
|
temp_matrix[i] = gf_exp[((i/k)*(i%k))%255]
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < k; i++ {
|
||||||
|
enc_matrix[i*(k+1)] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for row := k * k; row < n*k; row += k {
|
||||||
|
for col := 0; col < k; col++ {
|
||||||
|
pa := temp_matrix[row:]
|
||||||
|
pb := temp_matrix[col:]
|
||||||
|
acc := byte(0)
|
||||||
|
for i := 0; i < k; i, pa, pb = i+1, pa[1:], pb[k:] {
|
||||||
|
acc ^= gf_mul_table[pa[0]][pb[0]]
|
||||||
|
}
|
||||||
|
enc_matrix[row+col] = acc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vand_matrix has more columns than rows
|
||||||
|
// k rows, n columns.
|
||||||
|
vand_matrix := make([]byte, k*n)
|
||||||
|
vand_matrix[0] = 1
|
||||||
|
g := byte(1)
|
||||||
|
for row := 0; row < k; row++ {
|
||||||
|
a := byte(1)
|
||||||
|
for col := 1; col < n; col++ {
|
||||||
|
vand_matrix[row*n+col] = a // 2.pow(i * j) FIGURE IT OUT
|
||||||
|
a = gf_mul_table[g][a]
|
||||||
|
}
|
||||||
|
g = gf_mul_table[2][g]
|
||||||
|
}
|
||||||
|
|
||||||
|
return &FEC{
|
||||||
|
k: k,
|
||||||
|
n: n,
|
||||||
|
enc_matrix: enc_matrix,
|
||||||
|
vand_matrix: vand_matrix,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required returns the number of required pieces for reconstruction. This is
|
||||||
|
// the k value passed to NewFEC.
|
||||||
|
func (f *FEC) Required() int {
|
||||||
|
return f.k
|
||||||
|
}
|
||||||
|
|
||||||
|
// Total returns the number of total pieces that will be generated during
|
||||||
|
// encoding. This is the n value passed to NewFEC.
|
||||||
|
func (f *FEC) Total() int {
|
||||||
|
return f.n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode will take input data and encode to the total number of pieces n this
|
||||||
|
// *FEC is configured for. It will call the callback output n times.
|
||||||
|
//
|
||||||
|
// The input data must be a multiple of the required number of pieces k.
|
||||||
|
// Padding to this multiple is up to the caller.
|
||||||
|
//
|
||||||
|
// Note that the byte slices in Shares passed to output may be reused when
|
||||||
|
// output returns.
|
||||||
|
func (f *FEC) Encode(input []byte, output func(Share)) error {
|
||||||
|
size := len(input)
|
||||||
|
|
||||||
|
k := f.k
|
||||||
|
n := f.n
|
||||||
|
enc_matrix := f.enc_matrix
|
||||||
|
|
||||||
|
if size%k != 0 {
|
||||||
|
return fmt.Errorf("input length must be a multiple of %d", k)
|
||||||
|
}
|
||||||
|
|
||||||
|
block_size := size / k
|
||||||
|
|
||||||
|
for i := 0; i < k; i++ {
|
||||||
|
output(Share{
|
||||||
|
Number: i,
|
||||||
|
Data: input[i*block_size : i*block_size+block_size]})
|
||||||
|
}
|
||||||
|
|
||||||
|
fec_buf := make([]byte, block_size)
|
||||||
|
for i := k; i < n; i++ {
|
||||||
|
for j := range fec_buf {
|
||||||
|
fec_buf[j] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := 0; j < k; j++ {
|
||||||
|
addmul(fec_buf, input[j*block_size:j*block_size+block_size],
|
||||||
|
enc_matrix[i*k+j])
|
||||||
|
}
|
||||||
|
|
||||||
|
output(Share{
|
||||||
|
Number: i,
|
||||||
|
Data: fec_buf})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeSingle will take input data and encode it to output only for the num
|
||||||
|
// piece.
|
||||||
|
//
|
||||||
|
// The input data must be a multiple of the required number of pieces k.
|
||||||
|
// Padding to this multiple is up to the caller.
|
||||||
|
//
|
||||||
|
// The output must be exactly len(input) / k bytes.
|
||||||
|
//
|
||||||
|
// The num must be 0 <= num < n.
|
||||||
|
func (f *FEC) EncodeSingle(input, output []byte, num int) error {
|
||||||
|
size := len(input)
|
||||||
|
|
||||||
|
k := f.k
|
||||||
|
n := f.n
|
||||||
|
enc_matrix := f.enc_matrix
|
||||||
|
|
||||||
|
if num < 0 {
|
||||||
|
return errors.New("num must be non-negative")
|
||||||
|
}
|
||||||
|
|
||||||
|
if num >= n {
|
||||||
|
return fmt.Errorf("num must be less than %d", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if size%k != 0 {
|
||||||
|
return fmt.Errorf("input length must be a multiple of %d", k)
|
||||||
|
}
|
||||||
|
|
||||||
|
block_size := size / k
|
||||||
|
|
||||||
|
if len(output) != block_size {
|
||||||
|
return fmt.Errorf("output length must be %d", block_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
if num < k {
|
||||||
|
copy(output, input[num*block_size:])
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range output {
|
||||||
|
output[i] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < k; i++ {
|
||||||
|
addmul(output, input[i*block_size:i*block_size+block_size],
|
||||||
|
enc_matrix[num*k+i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Share represents a piece of the FEC-encoded data.
|
||||||
|
// Both fields are required.
|
||||||
|
type Share struct {
|
||||||
|
Number int
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy makes getting a deep copy of a Share easier. It will return an
|
||||||
|
// identical Share that uses all new memory locations.
|
||||||
|
func (s *Share) DeepCopy() (c Share) {
|
||||||
|
c.Number = s.Number
|
||||||
|
c.Data = append([]byte(nil), s.Data...)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type byNumber []Share
|
||||||
|
|
||||||
|
func (b byNumber) Len() int { return len(b) }
|
||||||
|
func (b byNumber) Less(i int, j int) bool { return b[i].Number < b[j].Number }
|
||||||
|
func (b byNumber) Swap(i int, j int) { b[i], b[j] = b[j], b[i] }
|
||||||
|
|
||||||
|
// Rebuild will take a list of corrected shares (pieces) and a callback output.
|
||||||
|
// output will be called k times ((*FEC).Required() times) with 1/k of the
|
||||||
|
// original data each time and the index of that data piece.
|
||||||
|
// Decode is usually preferred.
|
||||||
|
//
|
||||||
|
// Note that the data is not necessarily sent to output ordered by the piece
|
||||||
|
// number.
|
||||||
|
//
|
||||||
|
// Note that the byte slices in Shares passed to output may be reused when
|
||||||
|
// output returns.
|
||||||
|
//
|
||||||
|
// Rebuild assumes that you have already called Correct or did not need to.
|
||||||
|
func (f *FEC) Rebuild(shares []Share, output func(Share)) error {
|
||||||
|
k := f.k
|
||||||
|
n := f.n
|
||||||
|
enc_matrix := f.enc_matrix
|
||||||
|
|
||||||
|
if len(shares) < k {
|
||||||
|
return NotEnoughShares
|
||||||
|
}
|
||||||
|
|
||||||
|
share_size := len(shares[0].Data)
|
||||||
|
sort.Sort(byNumber(shares))
|
||||||
|
|
||||||
|
m_dec := make([]byte, k*k)
|
||||||
|
indexes := make([]int, k)
|
||||||
|
sharesv := make([][]byte, k)
|
||||||
|
|
||||||
|
shares_b_iter := 0
|
||||||
|
shares_e_iter := len(shares) - 1
|
||||||
|
|
||||||
|
for i := 0; i < k; i++ {
|
||||||
|
var share_id int
|
||||||
|
var share_data []byte
|
||||||
|
|
||||||
|
if share := shares[shares_b_iter]; share.Number == i {
|
||||||
|
share_id = share.Number
|
||||||
|
share_data = share.Data
|
||||||
|
shares_b_iter++
|
||||||
|
} else {
|
||||||
|
share := shares[shares_e_iter]
|
||||||
|
share_id = share.Number
|
||||||
|
share_data = share.Data
|
||||||
|
shares_e_iter--
|
||||||
|
}
|
||||||
|
|
||||||
|
if share_id >= n {
|
||||||
|
return fmt.Errorf("invalid share id: %d", share_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
if share_id < k {
|
||||||
|
m_dec[i*(k+1)] = 1
|
||||||
|
if output != nil {
|
||||||
|
output(Share{
|
||||||
|
Number: share_id,
|
||||||
|
Data: share_data})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
copy(m_dec[i*k:i*k+k], enc_matrix[share_id*k:])
|
||||||
|
}
|
||||||
|
|
||||||
|
sharesv[i] = share_data
|
||||||
|
indexes[i] = share_id
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := invertMatrix(m_dec, k); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := make([]byte, share_size)
|
||||||
|
for i := 0; i < len(indexes); i++ {
|
||||||
|
if indexes[i] >= k {
|
||||||
|
for j := range buf {
|
||||||
|
buf[j] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for col := 0; col < k; col++ {
|
||||||
|
addmul(buf, sharesv[col], m_dec[i*k+col])
|
||||||
|
}
|
||||||
|
|
||||||
|
if output != nil {
|
||||||
|
output(Share{
|
||||||
|
Number: i,
|
||||||
|
Data: buf})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
423
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/gf_alg.go
generated
vendored
Normal file
423
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/gf_alg.go
generated
vendored
Normal file
|
@ -0,0 +1,423 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2016-2017 Vivint, Inc.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package infectious
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
//
|
||||||
|
// basic helpers around gf(2^8) values
|
||||||
|
//
|
||||||
|
|
||||||
|
type gfVal byte
|
||||||
|
|
||||||
|
func gfConst(val byte) gfVal {
|
||||||
|
return gfVal(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b gfVal) pow(val int) gfVal {
|
||||||
|
out := gfVal(1)
|
||||||
|
mul_base := gf_mul_table[b][:]
|
||||||
|
for i := 0; i < val; i++ {
|
||||||
|
out = gfVal(mul_base[out])
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a gfVal) mul(b gfVal) gfVal {
|
||||||
|
return gfVal(gf_mul_table[a][b])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a gfVal) div(b gfVal) (gfVal, error) {
|
||||||
|
if b == 0 {
|
||||||
|
return 0, errors.New("divide by zero")
|
||||||
|
}
|
||||||
|
if a == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return gfVal(gf_exp[gf_log[a]-gf_log[b]]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a gfVal) add(b gfVal) gfVal {
|
||||||
|
return gfVal(a ^ b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a gfVal) isZero() bool {
|
||||||
|
return a == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a gfVal) inv() (gfVal, error) {
|
||||||
|
if a == 0 {
|
||||||
|
return 0, errors.New("invert zero")
|
||||||
|
}
|
||||||
|
return gfVal(gf_exp[255-gf_log[a]]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// basic helpers about a slice of gf(2^8) values
|
||||||
|
//
|
||||||
|
|
||||||
|
type gfVals []gfVal
|
||||||
|
|
||||||
|
func (a gfVals) unsafeBytes() []byte {
|
||||||
|
return *(*[]byte)(unsafe.Pointer(&a))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a gfVals) dot(b gfVals) gfVal {
|
||||||
|
out := gfConst(0)
|
||||||
|
for i := range a {
|
||||||
|
out = out.add(a[i].mul(b[i]))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a gfVals) String() string {
|
||||||
|
return fmt.Sprintf("%02x", a.unsafeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// basic helpers for dealing with polynomials with coefficients in gf(2^8)
|
||||||
|
//
|
||||||
|
|
||||||
|
type gfPoly []gfVal
|
||||||
|
|
||||||
|
func polyZero(size int) gfPoly {
|
||||||
|
out := make(gfPoly, size)
|
||||||
|
for i := range out {
|
||||||
|
out[i] = gfConst(0)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p gfPoly) isZero() bool {
|
||||||
|
for _, coef := range p {
|
||||||
|
if !coef.isZero() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p gfPoly) deg() int {
|
||||||
|
return len(p) - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p gfPoly) index(power int) gfVal {
|
||||||
|
if power < 0 {
|
||||||
|
return gfConst(0)
|
||||||
|
}
|
||||||
|
which := p.deg() - power
|
||||||
|
if which < 0 {
|
||||||
|
return gfConst(0)
|
||||||
|
}
|
||||||
|
return p[which]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p gfPoly) scale(factor gfVal) gfPoly {
|
||||||
|
out := make(gfPoly, len(p))
|
||||||
|
for i, coef := range p {
|
||||||
|
out[i] = coef.mul(factor)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *gfPoly) set(pow int, coef gfVal) {
|
||||||
|
which := p.deg() - pow
|
||||||
|
if which < 0 {
|
||||||
|
*p = append(polyZero(-which), *p...)
|
||||||
|
which = p.deg() - pow
|
||||||
|
}
|
||||||
|
(*p)[which] = coef
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p gfPoly) add(b gfPoly) gfPoly {
|
||||||
|
size := len(p)
|
||||||
|
if lb := len(b); lb > size {
|
||||||
|
size = lb
|
||||||
|
}
|
||||||
|
out := make(gfPoly, size)
|
||||||
|
for i := range out {
|
||||||
|
pi := p.index(i)
|
||||||
|
bi := b.index(i)
|
||||||
|
out.set(i, pi.add(bi))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p gfPoly) div(b gfPoly) (q, r gfPoly, err error) {
|
||||||
|
// sanitize the divisor by removing leading zeros.
|
||||||
|
for len(b) > 0 && b[0].isZero() {
|
||||||
|
b = b[1:]
|
||||||
|
}
|
||||||
|
if len(b) == 0 {
|
||||||
|
return nil, nil, errors.New("divide by zero")
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanitize the base poly as well
|
||||||
|
for len(p) > 0 && p[0].isZero() {
|
||||||
|
p = p[1:]
|
||||||
|
}
|
||||||
|
if len(p) == 0 {
|
||||||
|
return polyZero(1), polyZero(1), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const debug = false
|
||||||
|
indent := 2*len(b) + 1
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
fmt.Printf("%02x %02x\n", b, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
for b.deg() <= p.deg() {
|
||||||
|
leading_p := p.index(p.deg())
|
||||||
|
leading_b := b.index(b.deg())
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
fmt.Printf("leading_p: %02x leading_b: %02x\n",
|
||||||
|
leading_p, leading_b)
|
||||||
|
}
|
||||||
|
|
||||||
|
coef, err := leading_p.div(leading_b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
fmt.Printf("coef: %02x\n", coef)
|
||||||
|
}
|
||||||
|
|
||||||
|
q = append(q, coef)
|
||||||
|
|
||||||
|
scaled := b.scale(coef)
|
||||||
|
padded := append(scaled, polyZero(p.deg()-scaled.deg())...)
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
fmt.Printf("%s%02x\n", strings.Repeat(" ", indent), padded)
|
||||||
|
indent += 2
|
||||||
|
}
|
||||||
|
|
||||||
|
p = p.add(padded)
|
||||||
|
if !p[0].isZero() {
|
||||||
|
return nil, nil, fmt.Errorf("alg error: %x", p)
|
||||||
|
}
|
||||||
|
p = p[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
for len(p) > 1 && p[0].isZero() {
|
||||||
|
p = p[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return q, p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p gfPoly) eval(x gfVal) gfVal {
|
||||||
|
out := gfConst(0)
|
||||||
|
for i := 0; i <= p.deg(); i++ {
|
||||||
|
x_i := x.pow(i)
|
||||||
|
p_i := p.index(i)
|
||||||
|
out = out.add(p_i.mul(x_i))
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// basic helpers for matrices in gf(2^8)
|
||||||
|
//
|
||||||
|
|
||||||
|
type gfMat struct {
|
||||||
|
d gfVals
|
||||||
|
r, c int
|
||||||
|
}
|
||||||
|
|
||||||
|
func matrixNew(i, j int) gfMat {
|
||||||
|
return gfMat{
|
||||||
|
d: make(gfVals, i*j),
|
||||||
|
r: i, c: j,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m gfMat) String() (out string) {
|
||||||
|
if m.r == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < m.r-1; i++ {
|
||||||
|
out += fmt.Sprintln(m.indexRow(i))
|
||||||
|
}
|
||||||
|
out += fmt.Sprint(m.indexRow(m.r - 1))
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m gfMat) index(i, j int) int {
|
||||||
|
return m.c*i + j
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m gfMat) get(i, j int) gfVal {
|
||||||
|
return m.d[m.index(i, j)]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m gfMat) set(i, j int, val gfVal) {
|
||||||
|
m.d[m.index(i, j)] = val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m gfMat) indexRow(i int) gfVals {
|
||||||
|
return m.d[m.index(i, 0):m.index(i+1, 0)]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m gfMat) swapRow(i, j int) {
|
||||||
|
tmp := make(gfVals, m.r)
|
||||||
|
ri := m.indexRow(i)
|
||||||
|
rj := m.indexRow(j)
|
||||||
|
copy(tmp, ri)
|
||||||
|
copy(ri, rj)
|
||||||
|
copy(rj, tmp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m gfMat) scaleRow(i int, val gfVal) {
|
||||||
|
ri := m.indexRow(i)
|
||||||
|
for i := range ri {
|
||||||
|
ri[i] = ri[i].mul(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m gfMat) addmulRow(i, j int, val gfVal) {
|
||||||
|
ri := m.indexRow(i)
|
||||||
|
rj := m.indexRow(j)
|
||||||
|
addmul(rj.unsafeBytes(), ri.unsafeBytes(), byte(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// in place invert. the output is put into a and m is turned into the identity
|
||||||
|
// matrix. a is expected to be the identity matrix.
|
||||||
|
func (m gfMat) invertWith(a gfMat) error {
|
||||||
|
for i := 0; i < m.r; i++ {
|
||||||
|
p_row, p_val := i, m.get(i, i)
|
||||||
|
for j := i + 1; j < m.r && p_val.isZero(); j++ {
|
||||||
|
p_row, p_val = j, m.get(j, i)
|
||||||
|
}
|
||||||
|
if p_val.isZero() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if p_row != i {
|
||||||
|
m.swapRow(i, p_row)
|
||||||
|
a.swapRow(i, p_row)
|
||||||
|
}
|
||||||
|
|
||||||
|
inv, err := p_val.inv()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m.scaleRow(i, inv)
|
||||||
|
a.scaleRow(i, inv)
|
||||||
|
|
||||||
|
for j := i + 1; j < m.r; j++ {
|
||||||
|
leading := m.get(j, i)
|
||||||
|
m.addmulRow(i, j, leading)
|
||||||
|
a.addmulRow(i, j, leading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := m.r - 1; i > 0; i-- {
|
||||||
|
for j := i - 1; j >= 0; j-- {
|
||||||
|
trailing := m.get(j, i)
|
||||||
|
m.addmulRow(i, j, trailing)
|
||||||
|
a.addmulRow(i, j, trailing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// in place standardize.
|
||||||
|
func (m gfMat) standardize() error {
|
||||||
|
for i := 0; i < m.r; i++ {
|
||||||
|
p_row, p_val := i, m.get(i, i)
|
||||||
|
for j := i + 1; j < m.r && p_val.isZero(); j++ {
|
||||||
|
p_row, p_val = j, m.get(j, i)
|
||||||
|
}
|
||||||
|
if p_val.isZero() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if p_row != i {
|
||||||
|
m.swapRow(i, p_row)
|
||||||
|
}
|
||||||
|
|
||||||
|
inv, err := p_val.inv()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m.scaleRow(i, inv)
|
||||||
|
|
||||||
|
for j := i + 1; j < m.r; j++ {
|
||||||
|
leading := m.get(j, i)
|
||||||
|
m.addmulRow(i, j, leading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := m.r - 1; i > 0; i-- {
|
||||||
|
for j := i - 1; j >= 0; j-- {
|
||||||
|
trailing := m.get(j, i)
|
||||||
|
m.addmulRow(i, j, trailing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parity returns the new matrix because it changes dimensions and stuff. it
|
||||||
|
// can be done in place, but is easier to implement with a copy.
|
||||||
|
func (m gfMat) parity() gfMat {
|
||||||
|
// we assume m is in standard form already
|
||||||
|
// it is of form [I_r | P]
|
||||||
|
// our output will be [-P_transpose | I_(c - r)]
|
||||||
|
// but our field is of characteristic 2 so we do not need the negative.
|
||||||
|
|
||||||
|
// In terms of m:
|
||||||
|
// I_r has r rows and r columns.
|
||||||
|
// P has r rows and c-r columns.
|
||||||
|
// P_transpose has c-r rows, and r columns.
|
||||||
|
// I_(c-r) has c-r rows and c-r columns.
|
||||||
|
// so: out.r == c-r, out.c == r + c - r == c
|
||||||
|
|
||||||
|
out := matrixNew(m.c-m.r, m.c)
|
||||||
|
|
||||||
|
// step 1. fill in the identity. it starts at column offset r.
|
||||||
|
for i := 0; i < m.c-m.r; i++ {
|
||||||
|
out.set(i, i+m.r, gfConst(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 2: fill in the transposed P matrix. i and j are in terms of out.
|
||||||
|
for i := 0; i < m.c-m.r; i++ {
|
||||||
|
for j := 0; j < m.r; j++ {
|
||||||
|
out.set(i, j, m.get(j, i+m.r))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
182
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/math.go
generated
vendored
Normal file
182
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/math.go
generated
vendored
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
// (C) 1996-1998 Luigi Rizzo (luigi@iet.unipi.it)
|
||||||
|
// 2009-2010 Jack Lloyd (lloyd@randombit.net)
|
||||||
|
// 2011 Billy Brumley (billy.brumley@aalto.fi)
|
||||||
|
// 2016-2017 Vivint, Inc. (jeff.wendling@vivint.com)
|
||||||
|
//
|
||||||
|
// Portions derived from code by Phil Karn (karn@ka9q.ampr.org),
|
||||||
|
// Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari
|
||||||
|
// Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package infectious
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type pivotSearcher struct {
|
||||||
|
k int
|
||||||
|
ipiv []bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPivotSearcher(k int) *pivotSearcher {
|
||||||
|
return &pivotSearcher{
|
||||||
|
k: k,
|
||||||
|
ipiv: make([]bool, k),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pivotSearcher) search(col int, matrix []byte) (int, int, error) {
|
||||||
|
if p.ipiv[col] == false && matrix[col*p.k+col] != 0 {
|
||||||
|
p.ipiv[col] = true
|
||||||
|
return col, col, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for row := 0; row < p.k; row++ {
|
||||||
|
if p.ipiv[row] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < p.k; i++ {
|
||||||
|
if p.ipiv[i] == false && matrix[row*p.k+i] != 0 {
|
||||||
|
p.ipiv[i] = true
|
||||||
|
return row, i, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, 0, errors.New("pivot not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func swap(a, b *byte) {
|
||||||
|
tmp := *a
|
||||||
|
*a = *b
|
||||||
|
*b = tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(jeff): matrix is a K*K array, row major.
|
||||||
|
func invertMatrix(matrix []byte, k int) error {
|
||||||
|
pivot_searcher := newPivotSearcher(k)
|
||||||
|
indxc := make([]int, k)
|
||||||
|
indxr := make([]int, k)
|
||||||
|
id_row := make([]byte, k)
|
||||||
|
|
||||||
|
for col := 0; col < k; col++ {
|
||||||
|
icol, irow, err := pivot_searcher.search(col, matrix)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if irow != icol {
|
||||||
|
for i := 0; i < k; i++ {
|
||||||
|
swap(&matrix[irow*k+i], &matrix[icol*k+i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
indxr[col] = irow
|
||||||
|
indxc[col] = icol
|
||||||
|
pivot_row := matrix[icol*k:][:k]
|
||||||
|
c := pivot_row[icol]
|
||||||
|
|
||||||
|
if c == 0 {
|
||||||
|
return errors.New("singular matrix")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c != 1 {
|
||||||
|
c = gf_inverse[c]
|
||||||
|
pivot_row[icol] = 1
|
||||||
|
mul_c := gf_mul_table[c][:]
|
||||||
|
|
||||||
|
for i := 0; i < k; i++ {
|
||||||
|
pivot_row[i] = mul_c[pivot_row[i]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
id_row[icol] = 1
|
||||||
|
if !bytes.Equal(pivot_row, id_row) {
|
||||||
|
p := matrix
|
||||||
|
for i := 0; i < k; i++ {
|
||||||
|
if i != icol {
|
||||||
|
c = p[icol]
|
||||||
|
p[icol] = 0
|
||||||
|
addmul(p[:k], pivot_row, c)
|
||||||
|
}
|
||||||
|
p = p[k:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
id_row[icol] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < k; i++ {
|
||||||
|
if indxr[i] != indxc[i] {
|
||||||
|
for row := 0; row < k; row++ {
|
||||||
|
swap(&matrix[row*k+indxr[i]], &matrix[row*k+indxc[i]])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createInvertedVdm(vdm []byte, k int) {
|
||||||
|
if k == 1 {
|
||||||
|
vdm[0] = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
b := make([]byte, k)
|
||||||
|
c := make([]byte, k)
|
||||||
|
|
||||||
|
c[k-1] = 0
|
||||||
|
for i := 1; i < k; i++ {
|
||||||
|
mul_p_i := gf_mul_table[gf_exp[i]][:]
|
||||||
|
for j := k - 1 - (i - 1); j < k-1; j++ {
|
||||||
|
c[j] ^= mul_p_i[c[j+1]]
|
||||||
|
}
|
||||||
|
c[k-1] ^= gf_exp[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
for row := 0; row < k; row++ {
|
||||||
|
index := 0
|
||||||
|
if row != 0 {
|
||||||
|
index = int(gf_exp[row])
|
||||||
|
}
|
||||||
|
mul_p_row := gf_mul_table[index][:]
|
||||||
|
|
||||||
|
t := byte(1)
|
||||||
|
b[k-1] = 1
|
||||||
|
for i := k - 2; i >= 0; i-- {
|
||||||
|
b[i] = c[i+1] ^ mul_p_row[b[i+1]]
|
||||||
|
t = b[i] ^ mul_p_row[t]
|
||||||
|
}
|
||||||
|
|
||||||
|
mul_t_inv := gf_mul_table[gf_inverse[t]][:]
|
||||||
|
for col := 0; col < k; col++ {
|
||||||
|
vdm[col*k+row] = mul_t_inv[b[col]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
154
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/tables.go
generated
vendored
Normal file
154
cli/v2/picocrypt/vendor/github.com/HACKERALERT/infectious/tables.go
generated
vendored
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
// (C) 1996-1998 Luigi Rizzo (luigi@iet.unipi.it)
|
||||||
|
// 2009-2010 Jack Lloyd (lloyd@randombit.net)
|
||||||
|
// 2011 Billy Brumley (billy.brumley@aalto.fi)
|
||||||
|
// 2016-2017 Vivint, Inc. (jeff.wendling@vivint.com)
|
||||||
|
//
|
||||||
|
// Portions derived from code by Phil Karn (karn@ka9q.ampr.org),
|
||||||
|
// Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari
|
||||||
|
// Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package infectious
|
||||||
|
|
||||||
|
var (
|
||||||
|
gf_exp = [510]byte{
|
||||||
|
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1D, 0x3A, 0x74,
|
||||||
|
0xE8, 0xCD, 0x87, 0x13, 0x26, 0x4C, 0x98, 0x2D, 0x5A, 0xB4, 0x75,
|
||||||
|
0xEA, 0xC9, 0x8F, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x9D,
|
||||||
|
0x27, 0x4E, 0x9C, 0x25, 0x4A, 0x94, 0x35, 0x6A, 0xD4, 0xB5, 0x77,
|
||||||
|
0xEE, 0xC1, 0x9F, 0x23, 0x46, 0x8C, 0x05, 0x0A, 0x14, 0x28, 0x50,
|
||||||
|
0xA0, 0x5D, 0xBA, 0x69, 0xD2, 0xB9, 0x6F, 0xDE, 0xA1, 0x5F, 0xBE,
|
||||||
|
0x61, 0xC2, 0x99, 0x2F, 0x5E, 0xBC, 0x65, 0xCA, 0x89, 0x0F, 0x1E,
|
||||||
|
0x3C, 0x78, 0xF0, 0xFD, 0xE7, 0xD3, 0xBB, 0x6B, 0xD6, 0xB1, 0x7F,
|
||||||
|
0xFE, 0xE1, 0xDF, 0xA3, 0x5B, 0xB6, 0x71, 0xE2, 0xD9, 0xAF, 0x43,
|
||||||
|
0x86, 0x11, 0x22, 0x44, 0x88, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xBD,
|
||||||
|
0x67, 0xCE, 0x81, 0x1F, 0x3E, 0x7C, 0xF8, 0xED, 0xC7, 0x93, 0x3B,
|
||||||
|
0x76, 0xEC, 0xC5, 0x97, 0x33, 0x66, 0xCC, 0x85, 0x17, 0x2E, 0x5C,
|
||||||
|
0xB8, 0x6D, 0xDA, 0xA9, 0x4F, 0x9E, 0x21, 0x42, 0x84, 0x15, 0x2A,
|
||||||
|
0x54, 0xA8, 0x4D, 0x9A, 0x29, 0x52, 0xA4, 0x55, 0xAA, 0x49, 0x92,
|
||||||
|
0x39, 0x72, 0xE4, 0xD5, 0xB7, 0x73, 0xE6, 0xD1, 0xBF, 0x63, 0xC6,
|
||||||
|
0x91, 0x3F, 0x7E, 0xFC, 0xE5, 0xD7, 0xB3, 0x7B, 0xF6, 0xF1, 0xFF,
|
||||||
|
0xE3, 0xDB, 0xAB, 0x4B, 0x96, 0x31, 0x62, 0xC4, 0x95, 0x37, 0x6E,
|
||||||
|
0xDC, 0xA5, 0x57, 0xAE, 0x41, 0x82, 0x19, 0x32, 0x64, 0xC8, 0x8D,
|
||||||
|
0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xDD, 0xA7, 0x53, 0xA6, 0x51,
|
||||||
|
0xA2, 0x59, 0xB2, 0x79, 0xF2, 0xF9, 0xEF, 0xC3, 0x9B, 0x2B, 0x56,
|
||||||
|
0xAC, 0x45, 0x8A, 0x09, 0x12, 0x24, 0x48, 0x90, 0x3D, 0x7A, 0xF4,
|
||||||
|
0xF5, 0xF7, 0xF3, 0xFB, 0xEB, 0xCB, 0x8B, 0x0B, 0x16, 0x2C, 0x58,
|
||||||
|
0xB0, 0x7D, 0xFA, 0xE9, 0xCF, 0x83, 0x1B, 0x36, 0x6C, 0xD8, 0xAD,
|
||||||
|
0x47, 0x8E,
|
||||||
|
|
||||||
|
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1D, 0x3A, 0x74,
|
||||||
|
0xE8, 0xCD, 0x87, 0x13, 0x26, 0x4C, 0x98, 0x2D, 0x5A, 0xB4, 0x75,
|
||||||
|
0xEA, 0xC9, 0x8F, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x9D,
|
||||||
|
0x27, 0x4E, 0x9C, 0x25, 0x4A, 0x94, 0x35, 0x6A, 0xD4, 0xB5, 0x77,
|
||||||
|
0xEE, 0xC1, 0x9F, 0x23, 0x46, 0x8C, 0x05, 0x0A, 0x14, 0x28, 0x50,
|
||||||
|
0xA0, 0x5D, 0xBA, 0x69, 0xD2, 0xB9, 0x6F, 0xDE, 0xA1, 0x5F, 0xBE,
|
||||||
|
0x61, 0xC2, 0x99, 0x2F, 0x5E, 0xBC, 0x65, 0xCA, 0x89, 0x0F, 0x1E,
|
||||||
|
0x3C, 0x78, 0xF0, 0xFD, 0xE7, 0xD3, 0xBB, 0x6B, 0xD6, 0xB1, 0x7F,
|
||||||
|
0xFE, 0xE1, 0xDF, 0xA3, 0x5B, 0xB6, 0x71, 0xE2, 0xD9, 0xAF, 0x43,
|
||||||
|
0x86, 0x11, 0x22, 0x44, 0x88, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xBD,
|
||||||
|
0x67, 0xCE, 0x81, 0x1F, 0x3E, 0x7C, 0xF8, 0xED, 0xC7, 0x93, 0x3B,
|
||||||
|
0x76, 0xEC, 0xC5, 0x97, 0x33, 0x66, 0xCC, 0x85, 0x17, 0x2E, 0x5C,
|
||||||
|
0xB8, 0x6D, 0xDA, 0xA9, 0x4F, 0x9E, 0x21, 0x42, 0x84, 0x15, 0x2A,
|
||||||
|
0x54, 0xA8, 0x4D, 0x9A, 0x29, 0x52, 0xA4, 0x55, 0xAA, 0x49, 0x92,
|
||||||
|
0x39, 0x72, 0xE4, 0xD5, 0xB7, 0x73, 0xE6, 0xD1, 0xBF, 0x63, 0xC6,
|
||||||
|
0x91, 0x3F, 0x7E, 0xFC, 0xE5, 0xD7, 0xB3, 0x7B, 0xF6, 0xF1, 0xFF,
|
||||||
|
0xE3, 0xDB, 0xAB, 0x4B, 0x96, 0x31, 0x62, 0xC4, 0x95, 0x37, 0x6E,
|
||||||
|
0xDC, 0xA5, 0x57, 0xAE, 0x41, 0x82, 0x19, 0x32, 0x64, 0xC8, 0x8D,
|
||||||
|
0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xDD, 0xA7, 0x53, 0xA6, 0x51,
|
||||||
|
0xA2, 0x59, 0xB2, 0x79, 0xF2, 0xF9, 0xEF, 0xC3, 0x9B, 0x2B, 0x56,
|
||||||
|
0xAC, 0x45, 0x8A, 0x09, 0x12, 0x24, 0x48, 0x90, 0x3D, 0x7A, 0xF4,
|
||||||
|
0xF5, 0xF7, 0xF3, 0xFB, 0xEB, 0xCB, 0x8B, 0x0B, 0x16, 0x2C, 0x58,
|
||||||
|
0xB0, 0x7D, 0xFA, 0xE9, 0xCF, 0x83, 0x1B, 0x36, 0x6C, 0xD8, 0xAD,
|
||||||
|
0x47, 0x8E,
|
||||||
|
}
|
||||||
|
gf_log = [256]byte{
|
||||||
|
0xFF, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1A, 0xC6, 0x03, 0xDF, 0x33,
|
||||||
|
0xEE, 0x1B, 0x68, 0xC7, 0x4B, 0x04, 0x64, 0xE0, 0x0E, 0x34, 0x8D,
|
||||||
|
0xEF, 0x81, 0x1C, 0xC1, 0x69, 0xF8, 0xC8, 0x08, 0x4C, 0x71, 0x05,
|
||||||
|
0x8A, 0x65, 0x2F, 0xE1, 0x24, 0x0F, 0x21, 0x35, 0x93, 0x8E, 0xDA,
|
||||||
|
0xF0, 0x12, 0x82, 0x45, 0x1D, 0xB5, 0xC2, 0x7D, 0x6A, 0x27, 0xF9,
|
||||||
|
0xB9, 0xC9, 0x9A, 0x09, 0x78, 0x4D, 0xE4, 0x72, 0xA6, 0x06, 0xBF,
|
||||||
|
0x8B, 0x62, 0x66, 0xDD, 0x30, 0xFD, 0xE2, 0x98, 0x25, 0xB3, 0x10,
|
||||||
|
0x91, 0x22, 0x88, 0x36, 0xD0, 0x94, 0xCE, 0x8F, 0x96, 0xDB, 0xBD,
|
||||||
|
0xF1, 0xD2, 0x13, 0x5C, 0x83, 0x38, 0x46, 0x40, 0x1E, 0x42, 0xB6,
|
||||||
|
0xA3, 0xC3, 0x48, 0x7E, 0x6E, 0x6B, 0x3A, 0x28, 0x54, 0xFA, 0x85,
|
||||||
|
0xBA, 0x3D, 0xCA, 0x5E, 0x9B, 0x9F, 0x0A, 0x15, 0x79, 0x2B, 0x4E,
|
||||||
|
0xD4, 0xE5, 0xAC, 0x73, 0xF3, 0xA7, 0x57, 0x07, 0x70, 0xC0, 0xF7,
|
||||||
|
0x8C, 0x80, 0x63, 0x0D, 0x67, 0x4A, 0xDE, 0xED, 0x31, 0xC5, 0xFE,
|
||||||
|
0x18, 0xE3, 0xA5, 0x99, 0x77, 0x26, 0xB8, 0xB4, 0x7C, 0x11, 0x44,
|
||||||
|
0x92, 0xD9, 0x23, 0x20, 0x89, 0x2E, 0x37, 0x3F, 0xD1, 0x5B, 0x95,
|
||||||
|
0xBC, 0xCF, 0xCD, 0x90, 0x87, 0x97, 0xB2, 0xDC, 0xFC, 0xBE, 0x61,
|
||||||
|
0xF2, 0x56, 0xD3, 0xAB, 0x14, 0x2A, 0x5D, 0x9E, 0x84, 0x3C, 0x39,
|
||||||
|
0x53, 0x47, 0x6D, 0x41, 0xA2, 0x1F, 0x2D, 0x43, 0xD8, 0xB7, 0x7B,
|
||||||
|
0xA4, 0x76, 0xC4, 0x17, 0x49, 0xEC, 0x7F, 0x0C, 0x6F, 0xF6, 0x6C,
|
||||||
|
0xA1, 0x3B, 0x52, 0x29, 0x9D, 0x55, 0xAA, 0xFB, 0x60, 0x86, 0xB1,
|
||||||
|
0xBB, 0xCC, 0x3E, 0x5A, 0xCB, 0x59, 0x5F, 0xB0, 0x9C, 0xA9, 0xA0,
|
||||||
|
0x51, 0x0B, 0xF5, 0x16, 0xEB, 0x7A, 0x75, 0x2C, 0xD7, 0x4F, 0xAE,
|
||||||
|
0xD5, 0xE9, 0xE6, 0xE7, 0xAD, 0xE8, 0x74, 0xD6, 0xF4, 0xEA, 0xA8,
|
||||||
|
0x50, 0x58, 0xAF,
|
||||||
|
}
|
||||||
|
gf_inverse = [256]byte{
|
||||||
|
0x00, 0x01, 0x8E, 0xF4, 0x47, 0xA7, 0x7A, 0xBA, 0xAD, 0x9D, 0xDD,
|
||||||
|
0x98, 0x3D, 0xAA, 0x5D, 0x96, 0xD8, 0x72, 0xC0, 0x58, 0xE0, 0x3E,
|
||||||
|
0x4C, 0x66, 0x90, 0xDE, 0x55, 0x80, 0xA0, 0x83, 0x4B, 0x2A, 0x6C,
|
||||||
|
0xED, 0x39, 0x51, 0x60, 0x56, 0x2C, 0x8A, 0x70, 0xD0, 0x1F, 0x4A,
|
||||||
|
0x26, 0x8B, 0x33, 0x6E, 0x48, 0x89, 0x6F, 0x2E, 0xA4, 0xC3, 0x40,
|
||||||
|
0x5E, 0x50, 0x22, 0xCF, 0xA9, 0xAB, 0x0C, 0x15, 0xE1, 0x36, 0x5F,
|
||||||
|
0xF8, 0xD5, 0x92, 0x4E, 0xA6, 0x04, 0x30, 0x88, 0x2B, 0x1E, 0x16,
|
||||||
|
0x67, 0x45, 0x93, 0x38, 0x23, 0x68, 0x8C, 0x81, 0x1A, 0x25, 0x61,
|
||||||
|
0x13, 0xC1, 0xCB, 0x63, 0x97, 0x0E, 0x37, 0x41, 0x24, 0x57, 0xCA,
|
||||||
|
0x5B, 0xB9, 0xC4, 0x17, 0x4D, 0x52, 0x8D, 0xEF, 0xB3, 0x20, 0xEC,
|
||||||
|
0x2F, 0x32, 0x28, 0xD1, 0x11, 0xD9, 0xE9, 0xFB, 0xDA, 0x79, 0xDB,
|
||||||
|
0x77, 0x06, 0xBB, 0x84, 0xCD, 0xFE, 0xFC, 0x1B, 0x54, 0xA1, 0x1D,
|
||||||
|
0x7C, 0xCC, 0xE4, 0xB0, 0x49, 0x31, 0x27, 0x2D, 0x53, 0x69, 0x02,
|
||||||
|
0xF5, 0x18, 0xDF, 0x44, 0x4F, 0x9B, 0xBC, 0x0F, 0x5C, 0x0B, 0xDC,
|
||||||
|
0xBD, 0x94, 0xAC, 0x09, 0xC7, 0xA2, 0x1C, 0x82, 0x9F, 0xC6, 0x34,
|
||||||
|
0xC2, 0x46, 0x05, 0xCE, 0x3B, 0x0D, 0x3C, 0x9C, 0x08, 0xBE, 0xB7,
|
||||||
|
0x87, 0xE5, 0xEE, 0x6B, 0xEB, 0xF2, 0xBF, 0xAF, 0xC5, 0x64, 0x07,
|
||||||
|
0x7B, 0x95, 0x9A, 0xAE, 0xB6, 0x12, 0x59, 0xA5, 0x35, 0x65, 0xB8,
|
||||||
|
0xA3, 0x9E, 0xD2, 0xF7, 0x62, 0x5A, 0x85, 0x7D, 0xA8, 0x3A, 0x29,
|
||||||
|
0x71, 0xC8, 0xF6, 0xF9, 0x43, 0xD7, 0xD6, 0x10, 0x73, 0x76, 0x78,
|
||||||
|
0x99, 0x0A, 0x19, 0x91, 0x14, 0x3F, 0xE6, 0xF0, 0x86, 0xB1, 0xE2,
|
||||||
|
0xF1, 0xFA, 0x74, 0xF3, 0xB4, 0x6D, 0x21, 0xB2, 0x6A, 0xE3, 0xE7,
|
||||||
|
0xB5, 0xEA, 0x03, 0x8F, 0xD3, 0xC9, 0x42, 0xD4, 0xE8, 0x75, 0x7F,
|
||||||
|
0xFF, 0x7E, 0xFD,
|
||||||
|
}
|
||||||
|
gf_mul_table = [256][256]byte{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
for i := 0; i < 256; i++ {
|
||||||
|
for j := 0; j < 256; j++ {
|
||||||
|
log_i := int(gf_log[i])
|
||||||
|
log_j := int(gf_log[j])
|
||||||
|
gf_mul_table[i][j] = gf_exp[(log_i+log_j)%255]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 0; i < 256; i++ {
|
||||||
|
gf_mul_table[0][i], gf_mul_table[i][0] = 0, 0
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Andreas Auernhammer
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
316
cli/v2/picocrypt/vendor/github.com/HACKERALERT/serpent/sbox_ref.go
generated
vendored
Normal file
316
cli/v2/picocrypt/vendor/github.com/HACKERALERT/serpent/sbox_ref.go
generated
vendored
Normal file
|
@ -0,0 +1,316 @@
|
||||||
|
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package serpent
|
||||||
|
|
||||||
|
// The linear transformation of serpent
|
||||||
|
// This version, tries not to minimize the
|
||||||
|
// number of registers, but maximize parallism.
|
||||||
|
func linear(v0, v1, v2, v3 *uint32) {
|
||||||
|
t0 := ((*v0 << 13) | (*v0 >> (32 - 13)))
|
||||||
|
t2 := ((*v2 << 3) | (*v2 >> (32 - 3)))
|
||||||
|
t1 := *v1 ^ t0 ^ t2
|
||||||
|
t3 := *v3 ^ t2 ^ (t0 << 3)
|
||||||
|
*v1 = (t1 << 1) | (t1 >> (32 - 1))
|
||||||
|
*v3 = (t3 << 7) | (t3 >> (32 - 7))
|
||||||
|
t0 ^= *v1 ^ *v3
|
||||||
|
t2 ^= *v3 ^ (*v1 << 7)
|
||||||
|
*v0 = (t0 << 5) | (t0 >> (32 - 5))
|
||||||
|
*v2 = (t2 << 22) | (t2 >> (32 - 22))
|
||||||
|
}
|
||||||
|
|
||||||
|
// The inverse linear transformation of serpent
|
||||||
|
// This version, tries not to minimize the
|
||||||
|
// number of registers, but maximize parallism.
|
||||||
|
func linearInv(v0, v1, v2, v3 *uint32) {
|
||||||
|
t2 := (*v2 >> 22) | (*v2 << (32 - 22))
|
||||||
|
t0 := (*v0 >> 5) | (*v0 << (32 - 5))
|
||||||
|
t2 ^= *v3 ^ (*v1 << 7)
|
||||||
|
t0 ^= *v1 ^ *v3
|
||||||
|
t3 := (*v3 >> 7) | (*v3 << (32 - 7))
|
||||||
|
t1 := (*v1 >> 1) | (*v1 << (32 - 1))
|
||||||
|
*v3 = t3 ^ t2 ^ (t0 << 3)
|
||||||
|
*v1 = t1 ^ t0 ^ t2
|
||||||
|
*v2 = (t2 >> 3) | (t2 << (32 - 3))
|
||||||
|
*v0 = (t0 >> 13) | (t0 << (32 - 13))
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following functions sb0,sb1, ..., sb7 represent the 8 Serpent S-Boxes.
|
||||||
|
// sb0Inv til sb7Inv are the inverse functions (e.g. sb0Inv is the Inverse to sb0
|
||||||
|
// and vice versa).
|
||||||
|
// The S-Boxes differ from the original Serpent definitions. This is for
|
||||||
|
// optimisation. The functions use the Serpent S-Box improvements for (non x86)
|
||||||
|
// from Dr. B. R. Gladman and Sam Simpson.
|
||||||
|
|
||||||
|
// S-Box 0
|
||||||
|
func sb0(r0, r1, r2, r3 *uint32) {
|
||||||
|
t0 := *r0 ^ *r3
|
||||||
|
t1 := *r2 ^ t0
|
||||||
|
t2 := *r1 ^ t1
|
||||||
|
*r3 = (*r0 & *r3) ^ t2
|
||||||
|
t3 := *r0 ^ (*r1 & t0)
|
||||||
|
*r2 = t2 ^ (*r2 | t3)
|
||||||
|
t4 := *r3 & (t1 ^ t3)
|
||||||
|
*r1 = (^t1) ^ t4
|
||||||
|
*r0 = t4 ^ (^t3)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inverse S-Box 0
|
||||||
|
func sb0Inv(r0, r1, r2, r3 *uint32) {
|
||||||
|
t0 := ^(*r0)
|
||||||
|
t1 := *r0 ^ *r1
|
||||||
|
t2 := *r3 ^ (t0 | t1)
|
||||||
|
t3 := *r2 ^ t2
|
||||||
|
*r2 = t1 ^ t3
|
||||||
|
t4 := t0 ^ (*r3 & t1)
|
||||||
|
*r1 = t2 ^ (*r2 & t4)
|
||||||
|
*r3 = (*r0 & t2) ^ (t3 | *r1)
|
||||||
|
*r0 = *r3 ^ (t3 ^ t4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// S-Box 1
|
||||||
|
func sb1(r0, r1, r2, r3 *uint32) {
|
||||||
|
t0 := *r1 ^ (^(*r0))
|
||||||
|
t1 := *r2 ^ (*r0 | t0)
|
||||||
|
*r2 = *r3 ^ t1
|
||||||
|
t2 := *r1 ^ (*r3 | t0)
|
||||||
|
t3 := t0 ^ *r2
|
||||||
|
*r3 = t3 ^ (t1 & t2)
|
||||||
|
t4 := t1 ^ t2
|
||||||
|
*r1 = *r3 ^ t4
|
||||||
|
*r0 = t1 ^ (t3 & t4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inverse S-Box 1
|
||||||
|
func sb1Inv(r0, r1, r2, r3 *uint32) {
|
||||||
|
t0 := *r1 ^ *r3
|
||||||
|
t1 := *r0 ^ (*r1 & t0)
|
||||||
|
t2 := t0 ^ t1
|
||||||
|
*r3 = *r2 ^ t2
|
||||||
|
t3 := *r1 ^ (t0 & t1)
|
||||||
|
t4 := *r3 | t3
|
||||||
|
*r1 = t1 ^ t4
|
||||||
|
t5 := ^(*r1)
|
||||||
|
t6 := *r3 ^ t3
|
||||||
|
*r0 = t5 ^ t6
|
||||||
|
*r2 = t2 ^ (t5 | t6)
|
||||||
|
}
|
||||||
|
|
||||||
|
// S-Box 2
|
||||||
|
func sb2(r0, r1, r2, r3 *uint32) {
|
||||||
|
v0 := *r0 // save r0
|
||||||
|
v3 := *r3 // save r3
|
||||||
|
t0 := ^v0
|
||||||
|
t1 := *r1 ^ v3
|
||||||
|
t2 := *r2 & t0
|
||||||
|
*r0 = t1 ^ t2
|
||||||
|
t3 := *r2 ^ t0
|
||||||
|
t4 := *r2 ^ *r0
|
||||||
|
t5 := *r1 & t4
|
||||||
|
*r3 = t3 ^ t5
|
||||||
|
*r2 = v0 ^ ((v3 | t5) & (*r0 | t3))
|
||||||
|
*r1 = (t1 ^ *r3) ^ (*r2 ^ (v3 | t0))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inverse S-Box 2
|
||||||
|
func sb2Inv(r0, r1, r2, r3 *uint32) {
|
||||||
|
v0 := *r0 // save r0
|
||||||
|
v3 := *r3 // save r3
|
||||||
|
t0 := *r1 ^ v3
|
||||||
|
t1 := ^t0
|
||||||
|
t2 := v0 ^ *r2
|
||||||
|
t3 := *r2 ^ t0
|
||||||
|
t4 := *r1 & t3
|
||||||
|
*r0 = t2 ^ t4
|
||||||
|
t5 := v0 | t1
|
||||||
|
t6 := v3 ^ t5
|
||||||
|
t7 := t2 | t6
|
||||||
|
*r3 = t0 ^ t7
|
||||||
|
t8 := ^t3
|
||||||
|
t9 := *r0 | *r3
|
||||||
|
*r1 = t8 ^ t9
|
||||||
|
*r2 = (v3 & t8) ^ (t2 ^ t9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// S-Box 3
|
||||||
|
func sb3(r0, r1, r2, r3 *uint32) {
|
||||||
|
v1 := *r1 // save r1
|
||||||
|
v3 := *r3 // save r3
|
||||||
|
t0 := *r0 ^ *r1
|
||||||
|
t1 := *r0 & *r2
|
||||||
|
t2 := *r0 | *r3
|
||||||
|
t3 := *r2 ^ *r3
|
||||||
|
t4 := t0 & t2
|
||||||
|
t5 := t1 | t4
|
||||||
|
*r2 = t3 ^ t5
|
||||||
|
t6 := *r1 ^ t2
|
||||||
|
t7 := t5 ^ t6
|
||||||
|
t8 := t3 & t7
|
||||||
|
*r0 = t0 ^ t8
|
||||||
|
t9 := *r2 & *r0
|
||||||
|
*r1 = t7 ^ t9
|
||||||
|
*r3 = (v1 | v3) ^ (t3 ^ t9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inverse S-Box 3
|
||||||
|
func sb3Inv(r0, r1, r2, r3 *uint32) {
|
||||||
|
t0 := *r0 | *r1
|
||||||
|
t1 := *r1 ^ *r2
|
||||||
|
t2 := *r1 & t1
|
||||||
|
t3 := *r0 ^ t2
|
||||||
|
t4 := *r2 ^ t3
|
||||||
|
t5 := *r3 | t3
|
||||||
|
*r0 = t1 ^ t5
|
||||||
|
t6 := t1 | t5
|
||||||
|
t7 := *r3 ^ t6
|
||||||
|
*r2 = t4 ^ t7
|
||||||
|
t8 := t0 ^ t7
|
||||||
|
t9 := *r0 & t8
|
||||||
|
*r3 = t3 ^ t9
|
||||||
|
*r1 = *r3 ^ (*r0 ^ t8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// S-Box 4
|
||||||
|
func sb4(r0, r1, r2, r3 *uint32) {
|
||||||
|
v0 := *r0 // save r0
|
||||||
|
t0 := v0 ^ *r3
|
||||||
|
t1 := *r3 & t0
|
||||||
|
t2 := *r2 ^ t1
|
||||||
|
t3 := *r1 | t2
|
||||||
|
*r3 = t0 ^ t3
|
||||||
|
t4 := ^(*r1)
|
||||||
|
t5 := t0 | t4
|
||||||
|
*r0 = t2 ^ t5
|
||||||
|
t6 := v0 & *r0
|
||||||
|
t7 := t0 ^ t4
|
||||||
|
t8 := t3 & t7
|
||||||
|
*r2 = t6 ^ t8
|
||||||
|
*r1 = (v0 ^ t2) ^ (t7 & *r2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inverse S-Box 4
|
||||||
|
func sb4Inv(r0, r1, r2, r3 *uint32) {
|
||||||
|
v3 := *r3 // save r3
|
||||||
|
t0 := *r2 | v3
|
||||||
|
t1 := *r0 & t0
|
||||||
|
t2 := *r1 ^ t1
|
||||||
|
t3 := *r0 & t2
|
||||||
|
t4 := *r2 ^ t3
|
||||||
|
*r1 = v3 ^ t4
|
||||||
|
t5 := ^(*r0)
|
||||||
|
t6 := t4 & *r1
|
||||||
|
*r3 = t2 ^ t6
|
||||||
|
t7 := *r1 | t5
|
||||||
|
t8 := v3 ^ t7
|
||||||
|
*r0 = *r3 ^ t8
|
||||||
|
*r2 = (t2 & t8) ^ (*r1 ^ t5)
|
||||||
|
}
|
||||||
|
|
||||||
|
// S-Box 5
|
||||||
|
func sb5(r0, r1, r2, r3 *uint32) {
|
||||||
|
v1 := *r1 // save r1
|
||||||
|
t0 := ^(*r0)
|
||||||
|
t1 := *r0 ^ v1
|
||||||
|
t2 := *r0 ^ *r3
|
||||||
|
t3 := *r2 ^ t0
|
||||||
|
t4 := t1 | t2
|
||||||
|
*r0 = t3 ^ t4
|
||||||
|
t5 := *r3 & *r0
|
||||||
|
t6 := t1 ^ *r0
|
||||||
|
*r1 = t5 ^ t6
|
||||||
|
t7 := t0 | *r0
|
||||||
|
t8 := t1 | t5
|
||||||
|
t9 := t2 ^ t7
|
||||||
|
*r2 = t8 ^ t9
|
||||||
|
*r3 = (v1 ^ t5) ^ (*r1 & t9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inverse S-Box 5
|
||||||
|
func sb5Inv(r0, r1, r2, r3 *uint32) {
|
||||||
|
v0 := *r0 // save r0
|
||||||
|
v1 := *r1 // save r1
|
||||||
|
v3 := *r3 // save r3
|
||||||
|
t0 := ^(*r2)
|
||||||
|
t1 := v1 & t0
|
||||||
|
t2 := v3 ^ t1
|
||||||
|
t3 := v0 & t2
|
||||||
|
t4 := v1 ^ t0
|
||||||
|
*r3 = t3 ^ t4
|
||||||
|
t5 := v1 | *r3
|
||||||
|
t6 := v0 & t5
|
||||||
|
*r1 = t2 ^ t6
|
||||||
|
t7 := v0 | v3
|
||||||
|
t8 := t0 ^ t5
|
||||||
|
*r0 = t7 ^ t8
|
||||||
|
*r2 = (v1 & t7) ^ (t3 | (v0 ^ *r2))
|
||||||
|
}
|
||||||
|
|
||||||
|
// S-Box 6
|
||||||
|
func sb6(r0, r1, r2, r3 *uint32) {
|
||||||
|
t0 := ^(*r0)
|
||||||
|
t1 := *r0 ^ *r3
|
||||||
|
t2 := *r1 ^ t1
|
||||||
|
t3 := t0 | t1
|
||||||
|
t4 := *r2 ^ t3
|
||||||
|
*r1 = *r1 ^ t4
|
||||||
|
t5 := t1 | *r1
|
||||||
|
t6 := *r3 ^ t5
|
||||||
|
t7 := t4 & t6
|
||||||
|
*r2 = t2 ^ t7
|
||||||
|
t8 := t4 ^ t6
|
||||||
|
*r0 = *r2 ^ t8
|
||||||
|
*r3 = (^t4) ^ (t2 & t8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inverse S-Box 6
|
||||||
|
func sb6Inv(r0, r1, r2, r3 *uint32) {
|
||||||
|
v1 := *r1 // save r1
|
||||||
|
v3 := *r3 // save r3
|
||||||
|
t0 := ^(*r0)
|
||||||
|
t1 := *r0 ^ v1
|
||||||
|
t2 := *r2 ^ t1
|
||||||
|
t3 := *r2 | t0
|
||||||
|
t4 := v3 ^ t3
|
||||||
|
*r1 = t2 ^ t4
|
||||||
|
t5 := t2 & t4
|
||||||
|
t6 := t1 ^ t5
|
||||||
|
t7 := v1 | t6
|
||||||
|
*r3 = t4 ^ t7
|
||||||
|
t8 := v1 | *r3
|
||||||
|
*r0 = t6 ^ t8
|
||||||
|
*r2 = (v3 & t0) ^ (t2 ^ t8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// S-Box 7
|
||||||
|
func sb7(r0, r1, r2, r3 *uint32) {
|
||||||
|
t0 := *r1 ^ *r2
|
||||||
|
t1 := *r2 & t0
|
||||||
|
t2 := *r3 ^ t1
|
||||||
|
t3 := *r0 ^ t2
|
||||||
|
t4 := *r3 | t0
|
||||||
|
t5 := t3 & t4
|
||||||
|
*r1 = *r1 ^ t5
|
||||||
|
t6 := t2 | *r1
|
||||||
|
t7 := *r0 & t3
|
||||||
|
*r3 = t0 ^ t7
|
||||||
|
t8 := t3 ^ t6
|
||||||
|
t9 := *r3 & t8
|
||||||
|
*r2 = t2 ^ t9
|
||||||
|
*r0 = (^t8) ^ (*r3 & *r2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inverse S-Box 7
|
||||||
|
func sb7Inv(r0, r1, r2, r3 *uint32) {
|
||||||
|
v0 := *r0 // save r0
|
||||||
|
v3 := *r3 // save r3
|
||||||
|
t0 := *r2 | (v0 & *r1)
|
||||||
|
t1 := v3 & (v0 | *r1)
|
||||||
|
*r3 = t0 ^ t1
|
||||||
|
t2 := ^v3
|
||||||
|
t3 := *r1 ^ t1
|
||||||
|
t4 := t3 | (*r3 ^ t2)
|
||||||
|
*r1 = v0 ^ t4
|
||||||
|
*r0 = (*r2 ^ t3) ^ (v3 | *r1)
|
||||||
|
*r2 = (t0 ^ *r1) ^ (*r0 ^ (v0 & *r3))
|
||||||
|
}
|
119
cli/v2/picocrypt/vendor/github.com/HACKERALERT/serpent/serpent.go
generated
vendored
Normal file
119
cli/v2/picocrypt/vendor/github.com/HACKERALERT/serpent/serpent.go
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package serpent implements the Serpent block cipher
|
||||||
|
// submitted to the AES challenge. Serpent was designed by
|
||||||
|
// Ross Anderson, Eli Biham und Lars Knudsen.
|
||||||
|
// The block cipher takes a 128, 192 or 256 bit key and
|
||||||
|
// has a block size of 128 bit.
|
||||||
|
package serpent // import "github.com/aead/serpent"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/cipher"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BlockSize is the serpent block size in bytes.
|
||||||
|
const BlockSize = 16
|
||||||
|
|
||||||
|
const phi = 0x9e3779b9 // The Serpent phi constant (sqrt(5) - 1) * 2**31
|
||||||
|
|
||||||
|
var errKeySize = errors.New("invalid key size")
|
||||||
|
|
||||||
|
// NewCipher returns a new cipher.Block implementing the serpent block cipher.
|
||||||
|
// The key argument must be 128, 192 or 256 bit (16, 24, 32 byte).
|
||||||
|
func NewCipher(key []byte) (cipher.Block, error) {
|
||||||
|
if k := len(key); k != 16 && k != 24 && k != 32 {
|
||||||
|
return nil, errKeySize
|
||||||
|
}
|
||||||
|
s := &subkeys{}
|
||||||
|
s.keySchedule(key)
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// The 132 32 bit subkeys of serpent
|
||||||
|
type subkeys [132]uint32
|
||||||
|
|
||||||
|
func (s *subkeys) BlockSize() int { return BlockSize }
|
||||||
|
|
||||||
|
func (s *subkeys) Encrypt(dst, src []byte) {
|
||||||
|
if len(src) < BlockSize {
|
||||||
|
panic("src buffer to small")
|
||||||
|
}
|
||||||
|
if len(dst) < BlockSize {
|
||||||
|
panic("dst buffer to small")
|
||||||
|
}
|
||||||
|
encryptBlock(dst, src, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *subkeys) Decrypt(dst, src []byte) {
|
||||||
|
if len(src) < BlockSize {
|
||||||
|
panic("src buffer to small")
|
||||||
|
}
|
||||||
|
if len(dst) < BlockSize {
|
||||||
|
panic("dst buffer to small")
|
||||||
|
}
|
||||||
|
decryptBlock(dst, src, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The key schedule of serpent.
|
||||||
|
func (s *subkeys) keySchedule(key []byte) {
|
||||||
|
var k [16]uint32
|
||||||
|
j := 0
|
||||||
|
for i := 0; i+4 <= len(key); i += 4 {
|
||||||
|
k[j] = uint32(key[i]) | uint32(key[i+1])<<8 | uint32(key[i+2])<<16 | uint32(key[i+3])<<24
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
if j < 8 {
|
||||||
|
k[j] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 8; i < 16; i++ {
|
||||||
|
x := k[i-8] ^ k[i-5] ^ k[i-3] ^ k[i-1] ^ phi ^ uint32(i-8)
|
||||||
|
k[i] = (x << 11) | (x >> 21)
|
||||||
|
s[i-8] = k[i]
|
||||||
|
}
|
||||||
|
for i := 8; i < 132; i++ {
|
||||||
|
x := s[i-8] ^ s[i-5] ^ s[i-3] ^ s[i-1] ^ phi ^ uint32(i)
|
||||||
|
s[i] = (x << 11) | (x >> 21)
|
||||||
|
}
|
||||||
|
|
||||||
|
sb3(&s[0], &s[1], &s[2], &s[3])
|
||||||
|
sb2(&s[4], &s[5], &s[6], &s[7])
|
||||||
|
sb1(&s[8], &s[9], &s[10], &s[11])
|
||||||
|
sb0(&s[12], &s[13], &s[14], &s[15])
|
||||||
|
sb7(&s[16], &s[17], &s[18], &s[19])
|
||||||
|
sb6(&s[20], &s[21], &s[22], &s[23])
|
||||||
|
sb5(&s[24], &s[25], &s[26], &s[27])
|
||||||
|
sb4(&s[28], &s[29], &s[30], &s[31])
|
||||||
|
|
||||||
|
sb3(&s[32], &s[33], &s[34], &s[35])
|
||||||
|
sb2(&s[36], &s[37], &s[38], &s[39])
|
||||||
|
sb1(&s[40], &s[41], &s[42], &s[43])
|
||||||
|
sb0(&s[44], &s[45], &s[46], &s[47])
|
||||||
|
sb7(&s[48], &s[49], &s[50], &s[51])
|
||||||
|
sb6(&s[52], &s[53], &s[54], &s[55])
|
||||||
|
sb5(&s[56], &s[57], &s[58], &s[59])
|
||||||
|
sb4(&s[60], &s[61], &s[62], &s[63])
|
||||||
|
|
||||||
|
sb3(&s[64], &s[65], &s[66], &s[67])
|
||||||
|
sb2(&s[68], &s[69], &s[70], &s[71])
|
||||||
|
sb1(&s[72], &s[73], &s[74], &s[75])
|
||||||
|
sb0(&s[76], &s[77], &s[78], &s[79])
|
||||||
|
sb7(&s[80], &s[81], &s[82], &s[83])
|
||||||
|
sb6(&s[84], &s[85], &s[86], &s[87])
|
||||||
|
sb5(&s[88], &s[89], &s[90], &s[91])
|
||||||
|
sb4(&s[92], &s[93], &s[94], &s[95])
|
||||||
|
|
||||||
|
sb3(&s[96], &s[97], &s[98], &s[99])
|
||||||
|
sb2(&s[100], &s[101], &s[102], &s[103])
|
||||||
|
sb1(&s[104], &s[105], &s[106], &s[107])
|
||||||
|
sb0(&s[108], &s[109], &s[110], &s[111])
|
||||||
|
sb7(&s[112], &s[113], &s[114], &s[115])
|
||||||
|
sb6(&s[116], &s[117], &s[118], &s[119])
|
||||||
|
sb5(&s[120], &s[121], &s[122], &s[123])
|
||||||
|
sb4(&s[124], &s[125], &s[126], &s[127])
|
||||||
|
|
||||||
|
sb3(&s[128], &s[129], &s[130], &s[131])
|
||||||
|
}
|
276
cli/v2/picocrypt/vendor/github.com/HACKERALERT/serpent/serpent_ref.go
generated
vendored
Normal file
276
cli/v2/picocrypt/vendor/github.com/HACKERALERT/serpent/serpent_ref.go
generated
vendored
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package serpent
|
||||||
|
|
||||||
|
// Encrypts one block with the given 132 sub-keys sk.
|
||||||
|
func encryptBlock(dst, src []byte, sk *subkeys) {
|
||||||
|
// Transform the input block to 4 x 32 bit registers
|
||||||
|
r0 := uint32(src[0]) | uint32(src[1])<<8 | uint32(src[2])<<16 | uint32(src[3])<<24
|
||||||
|
r1 := uint32(src[4]) | uint32(src[5])<<8 | uint32(src[6])<<16 | uint32(src[7])<<24
|
||||||
|
r2 := uint32(src[8]) | uint32(src[9])<<8 | uint32(src[10])<<16 | uint32(src[11])<<24
|
||||||
|
r3 := uint32(src[12]) | uint32(src[13])<<8 | uint32(src[14])<<16 | uint32(src[15])<<24
|
||||||
|
|
||||||
|
// Encrypt the block with the 132 sub-keys and 8 S-Boxes
|
||||||
|
r0, r1, r2, r3 = r0^sk[0], r1^sk[1], r2^sk[2], r3^sk[3]
|
||||||
|
sb0(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[4], r1^sk[5], r2^sk[6], r3^sk[7]
|
||||||
|
sb1(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[8], r1^sk[9], r2^sk[10], r3^sk[11]
|
||||||
|
sb2(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[12], r1^sk[13], r2^sk[14], r3^sk[15]
|
||||||
|
sb3(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[16], r1^sk[17], r2^sk[18], r3^sk[19]
|
||||||
|
sb4(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[20], r1^sk[21], r2^sk[22], r3^sk[23]
|
||||||
|
sb5(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[24], r1^sk[25], r2^sk[26], r3^sk[27]
|
||||||
|
sb6(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[28], r1^sk[29], r2^sk[30], r3^sk[31]
|
||||||
|
sb7(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
|
||||||
|
r0, r1, r2, r3 = r0^sk[32], r1^sk[33], r2^sk[34], r3^sk[35]
|
||||||
|
sb0(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[36], r1^sk[37], r2^sk[38], r3^sk[39]
|
||||||
|
sb1(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[40], r1^sk[41], r2^sk[42], r3^sk[43]
|
||||||
|
sb2(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[44], r1^sk[45], r2^sk[46], r3^sk[47]
|
||||||
|
sb3(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[48], r1^sk[49], r2^sk[50], r3^sk[51]
|
||||||
|
sb4(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[52], r1^sk[53], r2^sk[54], r3^sk[55]
|
||||||
|
sb5(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[56], r1^sk[57], r2^sk[58], r3^sk[59]
|
||||||
|
sb6(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[60], r1^sk[61], r2^sk[62], r3^sk[63]
|
||||||
|
sb7(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
|
||||||
|
r0, r1, r2, r3 = r0^sk[64], r1^sk[65], r2^sk[66], r3^sk[67]
|
||||||
|
sb0(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[68], r1^sk[69], r2^sk[70], r3^sk[71]
|
||||||
|
sb1(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[72], r1^sk[73], r2^sk[74], r3^sk[75]
|
||||||
|
sb2(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[76], r1^sk[77], r2^sk[78], r3^sk[79]
|
||||||
|
sb3(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[80], r1^sk[81], r2^sk[82], r3^sk[83]
|
||||||
|
sb4(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[84], r1^sk[85], r2^sk[86], r3^sk[87]
|
||||||
|
sb5(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[88], r1^sk[89], r2^sk[90], r3^sk[91]
|
||||||
|
sb6(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[92], r1^sk[93], r2^sk[94], r3^sk[95]
|
||||||
|
sb7(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
|
||||||
|
r0, r1, r2, r3 = r0^sk[96], r1^sk[97], r2^sk[98], r3^sk[99]
|
||||||
|
sb0(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[100], r1^sk[101], r2^sk[102], r3^sk[103]
|
||||||
|
sb1(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[104], r1^sk[105], r2^sk[106], r3^sk[107]
|
||||||
|
sb2(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[108], r1^sk[109], r2^sk[110], r3^sk[111]
|
||||||
|
sb3(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[112], r1^sk[113], r2^sk[114], r3^sk[115]
|
||||||
|
sb4(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[116], r1^sk[117], r2^sk[118], r3^sk[119]
|
||||||
|
sb5(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[120], r1^sk[121], r2^sk[122], r3^sk[123]
|
||||||
|
sb6(&r0, &r1, &r2, &r3)
|
||||||
|
linear(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[124], r1^sk[125], r2^sk[126], r3^sk[127]
|
||||||
|
sb7(&r0, &r1, &r2, &r3)
|
||||||
|
|
||||||
|
// whitening
|
||||||
|
r0 ^= sk[128]
|
||||||
|
r1 ^= sk[129]
|
||||||
|
r2 ^= sk[130]
|
||||||
|
r3 ^= sk[131]
|
||||||
|
|
||||||
|
// write the encrypted block to the output
|
||||||
|
|
||||||
|
dst[0] = byte(r0)
|
||||||
|
dst[1] = byte(r0 >> 8)
|
||||||
|
dst[2] = byte(r0 >> 16)
|
||||||
|
dst[3] = byte(r0 >> 24)
|
||||||
|
dst[4] = byte(r1)
|
||||||
|
dst[5] = byte(r1 >> 8)
|
||||||
|
dst[6] = byte(r1 >> 16)
|
||||||
|
dst[7] = byte(r1 >> 24)
|
||||||
|
dst[8] = byte(r2)
|
||||||
|
dst[9] = byte(r2 >> 8)
|
||||||
|
dst[10] = byte(r2 >> 16)
|
||||||
|
dst[11] = byte(r2 >> 24)
|
||||||
|
dst[12] = byte(r3)
|
||||||
|
dst[13] = byte(r3 >> 8)
|
||||||
|
dst[14] = byte(r3 >> 16)
|
||||||
|
dst[15] = byte(r3 >> 24)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypts one block with the given 132 sub-keys sk.
|
||||||
|
func decryptBlock(dst, src []byte, sk *subkeys) {
|
||||||
|
// Transform the input block to 4 x 32 bit registers
|
||||||
|
r0 := uint32(src[0]) | uint32(src[1])<<8 | uint32(src[2])<<16 | uint32(src[3])<<24
|
||||||
|
r1 := uint32(src[4]) | uint32(src[5])<<8 | uint32(src[6])<<16 | uint32(src[7])<<24
|
||||||
|
r2 := uint32(src[8]) | uint32(src[9])<<8 | uint32(src[10])<<16 | uint32(src[11])<<24
|
||||||
|
r3 := uint32(src[12]) | uint32(src[13])<<8 | uint32(src[14])<<16 | uint32(src[15])<<24
|
||||||
|
|
||||||
|
// undo whitening
|
||||||
|
r0 ^= sk[128]
|
||||||
|
r1 ^= sk[129]
|
||||||
|
r2 ^= sk[130]
|
||||||
|
r3 ^= sk[131]
|
||||||
|
|
||||||
|
// Decrypt the block with the 132 sub-keys and 8 S-Boxes
|
||||||
|
sb7Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[124], r1^sk[125], r2^sk[126], r3^sk[127]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb6Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[120], r1^sk[121], r2^sk[122], r3^sk[123]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb5Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[116], r1^sk[117], r2^sk[118], r3^sk[119]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb4Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[112], r1^sk[113], r2^sk[114], r3^sk[115]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb3Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[108], r1^sk[109], r2^sk[110], r3^sk[111]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb2Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[104], r1^sk[105], r2^sk[106], r3^sk[107]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb1Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[100], r1^sk[101], r2^sk[102], r3^sk[103]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb0Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[96], r1^sk[97], r2^sk[98], r3^sk[99]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
|
||||||
|
sb7Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[92], r1^sk[93], r2^sk[94], r3^sk[95]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb6Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[88], r1^sk[89], r2^sk[90], r3^sk[91]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb5Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[84], r1^sk[85], r2^sk[86], r3^sk[87]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb4Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[80], r1^sk[81], r2^sk[82], r3^sk[83]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb3Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[76], r1^sk[77], r2^sk[78], r3^sk[79]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb2Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[72], r1^sk[73], r2^sk[74], r3^sk[75]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb1Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[68], r1^sk[69], r2^sk[70], r3^sk[71]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb0Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[64], r1^sk[65], r2^sk[66], r3^sk[67]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
|
||||||
|
sb7Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[60], r1^sk[61], r2^sk[62], r3^sk[63]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb6Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[56], r1^sk[57], r2^sk[58], r3^sk[59]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb5Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[52], r1^sk[53], r2^sk[54], r3^sk[55]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb4Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[48], r1^sk[49], r2^sk[50], r3^sk[51]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb3Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[44], r1^sk[45], r2^sk[46], r3^sk[47]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb2Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[40], r1^sk[41], r2^sk[42], r3^sk[43]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb1Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[36], r1^sk[37], r2^sk[38], r3^sk[39]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb0Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[32], r1^sk[33], r2^sk[34], r3^sk[35]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
|
||||||
|
sb7Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[28], r1^sk[29], r2^sk[30], r3^sk[31]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb6Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[24], r1^sk[25], r2^sk[26], r3^sk[27]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb5Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[20], r1^sk[21], r2^sk[22], r3^sk[23]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb4Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[16], r1^sk[17], r2^sk[18], r3^sk[19]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb3Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[12], r1^sk[13], r2^sk[14], r3^sk[15]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb2Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[8], r1^sk[9], r2^sk[10], r3^sk[11]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb1Inv(&r0, &r1, &r2, &r3)
|
||||||
|
r0, r1, r2, r3 = r0^sk[4], r1^sk[5], r2^sk[6], r3^sk[7]
|
||||||
|
linearInv(&r0, &r1, &r2, &r3)
|
||||||
|
sb0Inv(&r0, &r1, &r2, &r3)
|
||||||
|
|
||||||
|
r0 ^= sk[0]
|
||||||
|
r1 ^= sk[1]
|
||||||
|
r2 ^= sk[2]
|
||||||
|
r3 ^= sk[3]
|
||||||
|
|
||||||
|
// write the decrypted block to the output
|
||||||
|
dst[0] = byte(r0)
|
||||||
|
dst[1] = byte(r0 >> 8)
|
||||||
|
dst[2] = byte(r0 >> 16)
|
||||||
|
dst[3] = byte(r0 >> 24)
|
||||||
|
dst[4] = byte(r1)
|
||||||
|
dst[5] = byte(r1 >> 8)
|
||||||
|
dst[6] = byte(r1 >> 16)
|
||||||
|
dst[7] = byte(r1 >> 24)
|
||||||
|
dst[8] = byte(r2)
|
||||||
|
dst[9] = byte(r2 >> 8)
|
||||||
|
dst[10] = byte(r2 >> 16)
|
||||||
|
dst[11] = byte(r2 >> 24)
|
||||||
|
dst[12] = byte(r3)
|
||||||
|
dst[13] = byte(r3 >> 8)
|
||||||
|
dst[14] = byte(r3 >> 16)
|
||||||
|
dst[15] = byte(r3 >> 24)
|
||||||
|
}
|
15
cli/v2/picocrypt/vendor/github.com/mitchellh/colorstring/.travis.yml
generated
vendored
Normal file
15
cli/v2/picocrypt/vendor/github.com/mitchellh/colorstring/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.0
|
||||||
|
- 1.1
|
||||||
|
- 1.2
|
||||||
|
- 1.3
|
||||||
|
- tip
|
||||||
|
|
||||||
|
script:
|
||||||
|
- go test
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- go: tip
|
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Mitchell Hashimoto
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
30
cli/v2/picocrypt/vendor/github.com/mitchellh/colorstring/README.md
generated
vendored
Normal file
30
cli/v2/picocrypt/vendor/github.com/mitchellh/colorstring/README.md
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# colorstring [![Build Status](https://travis-ci.org/mitchellh/colorstring.svg)](https://travis-ci.org/mitchellh/colorstring)
|
||||||
|
|
||||||
|
colorstring is a [Go](http://www.golang.org) library for outputting colored
|
||||||
|
strings to a console using a simple inline syntax in your string to specify
|
||||||
|
the color to print as.
|
||||||
|
|
||||||
|
For example, the string `[blue]hello [red]world` would output the text
|
||||||
|
"hello world" in two colors. The API of colorstring allows for easily disabling
|
||||||
|
colors, adding aliases, etc.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Standard `go get`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ go get github.com/mitchellh/colorstring
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage & Example
|
||||||
|
|
||||||
|
For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/colorstring).
|
||||||
|
|
||||||
|
Usage is easy enough:
|
||||||
|
|
||||||
|
```go
|
||||||
|
colorstring.Println("[blue]Hello [red]World!")
|
||||||
|
```
|
||||||
|
|
||||||
|
Additionally, the `Colorize` struct can be used to set options such as
|
||||||
|
custom colors, color disabling, etc.
|
244
cli/v2/picocrypt/vendor/github.com/mitchellh/colorstring/colorstring.go
generated
vendored
Normal file
244
cli/v2/picocrypt/vendor/github.com/mitchellh/colorstring/colorstring.go
generated
vendored
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
// colorstring provides functions for colorizing strings for terminal
|
||||||
|
// output.
|
||||||
|
package colorstring
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Color colorizes your strings using the default settings.
|
||||||
|
//
|
||||||
|
// Strings given to Color should use the syntax `[color]` to specify the
|
||||||
|
// color for text following. For example: `[blue]Hello` will return "Hello"
|
||||||
|
// in blue. See DefaultColors for all the supported colors and attributes.
|
||||||
|
//
|
||||||
|
// If an unrecognized color is given, it is ignored and assumed to be part
|
||||||
|
// of the string. For example: `[hi]world` will result in "[hi]world".
|
||||||
|
//
|
||||||
|
// A color reset is appended to the end of every string. This will reset
|
||||||
|
// the color of following strings when you output this text to the same
|
||||||
|
// terminal session.
|
||||||
|
//
|
||||||
|
// If you want to customize any of this behavior, use the Colorize struct.
|
||||||
|
func Color(v string) string {
|
||||||
|
return def.Color(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ColorPrefix returns the color sequence that prefixes the given text.
|
||||||
|
//
|
||||||
|
// This is useful when wrapping text if you want to inherit the color
|
||||||
|
// of the wrapped text. For example, "[green]foo" will return "[green]".
|
||||||
|
// If there is no color sequence, then this will return "".
|
||||||
|
func ColorPrefix(v string) string {
|
||||||
|
return def.ColorPrefix(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Colorize colorizes your strings, giving you the ability to customize
|
||||||
|
// some of the colorization process.
|
||||||
|
//
|
||||||
|
// The options in Colorize can be set to customize colorization. If you're
|
||||||
|
// only interested in the defaults, just use the top Color function directly,
|
||||||
|
// which creates a default Colorize.
|
||||||
|
type Colorize struct {
|
||||||
|
// Colors maps a color string to the code for that color. The code
|
||||||
|
// is a string so that you can use more complex colors to set foreground,
|
||||||
|
// background, attributes, etc. For example, "boldblue" might be
|
||||||
|
// "1;34"
|
||||||
|
Colors map[string]string
|
||||||
|
|
||||||
|
// If true, color attributes will be ignored. This is useful if you're
|
||||||
|
// outputting to a location that doesn't support colors and you just
|
||||||
|
// want the strings returned.
|
||||||
|
Disable bool
|
||||||
|
|
||||||
|
// Reset, if true, will reset the color after each colorization by
|
||||||
|
// adding a reset code at the end.
|
||||||
|
Reset bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Color colorizes a string according to the settings setup in the struct.
|
||||||
|
//
|
||||||
|
// For more details on the syntax, see the top-level Color function.
|
||||||
|
func (c *Colorize) Color(v string) string {
|
||||||
|
matches := parseRe.FindAllStringIndex(v, -1)
|
||||||
|
if len(matches) == 0 {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
result := new(bytes.Buffer)
|
||||||
|
colored := false
|
||||||
|
m := []int{0, 0}
|
||||||
|
for _, nm := range matches {
|
||||||
|
// Write the text in between this match and the last
|
||||||
|
result.WriteString(v[m[1]:nm[0]])
|
||||||
|
m = nm
|
||||||
|
|
||||||
|
var replace string
|
||||||
|
if code, ok := c.Colors[v[m[0]+1:m[1]-1]]; ok {
|
||||||
|
colored = true
|
||||||
|
|
||||||
|
if !c.Disable {
|
||||||
|
replace = fmt.Sprintf("\033[%sm", code)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
replace = v[m[0]:m[1]]
|
||||||
|
}
|
||||||
|
|
||||||
|
result.WriteString(replace)
|
||||||
|
}
|
||||||
|
result.WriteString(v[m[1]:])
|
||||||
|
|
||||||
|
if colored && c.Reset && !c.Disable {
|
||||||
|
// Write the clear byte at the end
|
||||||
|
result.WriteString("\033[0m")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ColorPrefix returns the first color sequence that exists in this string.
|
||||||
|
//
|
||||||
|
// For example: "[green]foo" would return "[green]". If no color sequence
|
||||||
|
// exists, then "" is returned. This is especially useful when wrapping
|
||||||
|
// colored texts to inherit the color of the wrapped text.
|
||||||
|
func (c *Colorize) ColorPrefix(v string) string {
|
||||||
|
return prefixRe.FindString(strings.TrimSpace(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultColors are the default colors used when colorizing.
|
||||||
|
//
|
||||||
|
// If the color is surrounded in underscores, such as "_blue_", then that
|
||||||
|
// color will be used for the background color.
|
||||||
|
var DefaultColors map[string]string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
DefaultColors = map[string]string{
|
||||||
|
// Default foreground/background colors
|
||||||
|
"default": "39",
|
||||||
|
"_default_": "49",
|
||||||
|
|
||||||
|
// Foreground colors
|
||||||
|
"black": "30",
|
||||||
|
"red": "31",
|
||||||
|
"green": "32",
|
||||||
|
"yellow": "33",
|
||||||
|
"blue": "34",
|
||||||
|
"magenta": "35",
|
||||||
|
"cyan": "36",
|
||||||
|
"light_gray": "37",
|
||||||
|
"dark_gray": "90",
|
||||||
|
"light_red": "91",
|
||||||
|
"light_green": "92",
|
||||||
|
"light_yellow": "93",
|
||||||
|
"light_blue": "94",
|
||||||
|
"light_magenta": "95",
|
||||||
|
"light_cyan": "96",
|
||||||
|
"white": "97",
|
||||||
|
|
||||||
|
// Background colors
|
||||||
|
"_black_": "40",
|
||||||
|
"_red_": "41",
|
||||||
|
"_green_": "42",
|
||||||
|
"_yellow_": "43",
|
||||||
|
"_blue_": "44",
|
||||||
|
"_magenta_": "45",
|
||||||
|
"_cyan_": "46",
|
||||||
|
"_light_gray_": "47",
|
||||||
|
"_dark_gray_": "100",
|
||||||
|
"_light_red_": "101",
|
||||||
|
"_light_green_": "102",
|
||||||
|
"_light_yellow_": "103",
|
||||||
|
"_light_blue_": "104",
|
||||||
|
"_light_magenta_": "105",
|
||||||
|
"_light_cyan_": "106",
|
||||||
|
"_white_": "107",
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
"bold": "1",
|
||||||
|
"dim": "2",
|
||||||
|
"underline": "4",
|
||||||
|
"blink_slow": "5",
|
||||||
|
"blink_fast": "6",
|
||||||
|
"invert": "7",
|
||||||
|
"hidden": "8",
|
||||||
|
|
||||||
|
// Reset to reset everything to their defaults
|
||||||
|
"reset": "0",
|
||||||
|
"reset_bold": "21",
|
||||||
|
}
|
||||||
|
|
||||||
|
def = Colorize{
|
||||||
|
Colors: DefaultColors,
|
||||||
|
Reset: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var def Colorize
|
||||||
|
var parseReRaw = `\[[a-z0-9_-]+\]`
|
||||||
|
var parseRe = regexp.MustCompile(`(?i)` + parseReRaw)
|
||||||
|
var prefixRe = regexp.MustCompile(`^(?i)(` + parseReRaw + `)+`)
|
||||||
|
|
||||||
|
// Print is a convenience wrapper for fmt.Print with support for color codes.
|
||||||
|
//
|
||||||
|
// Print formats using the default formats for its operands and writes to
|
||||||
|
// standard output with support for color codes. Spaces are added between
|
||||||
|
// operands when neither is a string. It returns the number of bytes written
|
||||||
|
// and any write error encountered.
|
||||||
|
func Print(a string) (n int, err error) {
|
||||||
|
return fmt.Print(Color(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Println is a convenience wrapper for fmt.Println with support for color
|
||||||
|
// codes.
|
||||||
|
//
|
||||||
|
// Println formats using the default formats for its operands and writes to
|
||||||
|
// standard output with support for color codes. Spaces are always added
|
||||||
|
// between operands and a newline is appended. It returns the number of bytes
|
||||||
|
// written and any write error encountered.
|
||||||
|
func Println(a string) (n int, err error) {
|
||||||
|
return fmt.Println(Color(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printf is a convenience wrapper for fmt.Printf with support for color codes.
|
||||||
|
//
|
||||||
|
// Printf formats according to a format specifier and writes to standard output
|
||||||
|
// with support for color codes. It returns the number of bytes written and any
|
||||||
|
// write error encountered.
|
||||||
|
func Printf(format string, a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Printf(Color(format), a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprint is a convenience wrapper for fmt.Fprint with support for color codes.
|
||||||
|
//
|
||||||
|
// Fprint formats using the default formats for its operands and writes to w
|
||||||
|
// with support for color codes. Spaces are added between operands when neither
|
||||||
|
// is a string. It returns the number of bytes written and any write error
|
||||||
|
// encountered.
|
||||||
|
func Fprint(w io.Writer, a string) (n int, err error) {
|
||||||
|
return fmt.Fprint(w, Color(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprintln is a convenience wrapper for fmt.Fprintln with support for color
|
||||||
|
// codes.
|
||||||
|
//
|
||||||
|
// Fprintln formats using the default formats for its operands and writes to w
|
||||||
|
// with support for color codes. Spaces are always added between operands and a
|
||||||
|
// newline is appended. It returns the number of bytes written and any write
|
||||||
|
// error encountered.
|
||||||
|
func Fprintln(w io.Writer, a string) (n int, err error) {
|
||||||
|
return fmt.Fprintln(w, Color(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprintf is a convenience wrapper for fmt.Fprintf with support for color
|
||||||
|
// codes.
|
||||||
|
//
|
||||||
|
// Fprintf formats according to a format specifier and writes to w with support
|
||||||
|
// for color codes. It returns the number of bytes written and any write error
|
||||||
|
// encountered.
|
||||||
|
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Fprintf(w, Color(format), a...)
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Oliver Kuederle
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,137 @@
|
||||||
|
# Unicode Text Segmentation for Go
|
||||||
|
|
||||||
|
[![Go Reference](https://pkg.go.dev/badge/github.com/rivo/uniseg.svg)](https://pkg.go.dev/github.com/rivo/uniseg)
|
||||||
|
[![Go Report](https://img.shields.io/badge/go%20report-A%2B-brightgreen.svg)](https://goreportcard.com/report/github.com/rivo/uniseg)
|
||||||
|
|
||||||
|
This Go package implements Unicode Text Segmentation according to [Unicode Standard Annex #29](https://unicode.org/reports/tr29/), Unicode Line Breaking according to [Unicode Standard Annex #14](https://unicode.org/reports/tr14/) (Unicode version 15.0.0), and monospace font string width calculation similar to [wcwidth](https://man7.org/linux/man-pages/man3/wcwidth.3.html).
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
### Grapheme Clusters
|
||||||
|
|
||||||
|
In Go, [strings are read-only slices of bytes](https://go.dev/blog/strings). They can be turned into Unicode code points using the `for` loop or by casting: `[]rune(str)`. However, multiple code points may be combined into one user-perceived character or what the Unicode specification calls "grapheme cluster". Here are some examples:
|
||||||
|
|
||||||
|
|String|Bytes (UTF-8)|Code points (runes)|Grapheme clusters|
|
||||||
|
|-|-|-|-|
|
||||||
|
|Käse|6 bytes: `4b 61 cc 88 73 65`|5 code points: `4b 61 308 73 65`|4 clusters: `[4b],[61 308],[73],[65]`|
|
||||||
|
|🏳️🌈|14 bytes: `f0 9f 8f b3 ef b8 8f e2 80 8d f0 9f 8c 88`|4 code points: `1f3f3 fe0f 200d 1f308`|1 cluster: `[1f3f3 fe0f 200d 1f308]`|
|
||||||
|
|🇩🇪|8 bytes: `f0 9f 87 a9 f0 9f 87 aa`|2 code points: `1f1e9 1f1ea`|1 cluster: `[1f1e9 1f1ea]`|
|
||||||
|
|
||||||
|
This package provides tools to iterate over these grapheme clusters. This may be used to determine the number of user-perceived characters, to split strings in their intended places, or to extract individual characters which form a unit.
|
||||||
|
|
||||||
|
### Word Boundaries
|
||||||
|
|
||||||
|
Word boundaries are used in a number of different contexts. The most familiar ones are selection (double-click mouse selection), cursor movement ("move to next word" control-arrow keys), and the dialog option "Whole Word Search" for search and replace. They are also used in database queries, to determine whether elements are within a certain number of words of one another. Searching may also use word boundaries in determining matching items. This package provides tools to determine word boundaries within strings.
|
||||||
|
|
||||||
|
### Sentence Boundaries
|
||||||
|
|
||||||
|
Sentence boundaries are often used for triple-click or some other method of selecting or iterating through blocks of text that are larger than single words. They are also used to determine whether words occur within the same sentence in database queries. This package provides tools to determine sentence boundaries within strings.
|
||||||
|
|
||||||
|
### Line Breaking
|
||||||
|
|
||||||
|
Line breaking, also known as word wrapping, is the process of breaking a section of text into lines such that it will fit in the available width of a page, window or other display area. This package provides tools to determine where a string may or may not be broken and where it must be broken (for example after newline characters).
|
||||||
|
|
||||||
|
### Monospace Width
|
||||||
|
|
||||||
|
Most terminals or text displays / text editors using a monospace font (for example source code editors) use a fixed width for each character. Some characters such as emojis or characters found in Asian and other languages may take up more than one character cell. This package provides tools to determine the number of cells a string will take up when displayed in a monospace font. See [here](https://pkg.go.dev/github.com/rivo/uniseg#hdr-Monospace_Width) for more information.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get github.com/rivo/uniseg
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Counting Characters in a String
|
||||||
|
|
||||||
|
```go
|
||||||
|
n := uniseg.GraphemeClusterCount("🇩🇪🏳️🌈")
|
||||||
|
fmt.Println(n)
|
||||||
|
// 2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Calculating the Monospace String Width
|
||||||
|
|
||||||
|
```go
|
||||||
|
width := uniseg.StringWidth("🇩🇪🏳️🌈!")
|
||||||
|
fmt.Println(width)
|
||||||
|
// 5
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) Class
|
||||||
|
|
||||||
|
This is the most convenient method of iterating over grapheme clusters:
|
||||||
|
|
||||||
|
```go
|
||||||
|
gr := uniseg.NewGraphemes("👍🏼!")
|
||||||
|
for gr.Next() {
|
||||||
|
fmt.Printf("%x ", gr.Runes())
|
||||||
|
}
|
||||||
|
// [1f44d 1f3fc] [21]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using the [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) Function
|
||||||
|
|
||||||
|
This avoids allocating a new `Graphemes` object but it requires the handling of states and boundaries:
|
||||||
|
|
||||||
|
```go
|
||||||
|
str := "🇩🇪🏳️🌈"
|
||||||
|
state := -1
|
||||||
|
var c string
|
||||||
|
for len(str) > 0 {
|
||||||
|
c, str, _, state = uniseg.StepString(str, state)
|
||||||
|
fmt.Printf("%x ", []rune(c))
|
||||||
|
}
|
||||||
|
// [1f1e9 1f1ea] [1f3f3 fe0f 200d 1f308]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced Examples
|
||||||
|
|
||||||
|
The [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class offers the most convenient way to access all functionality of this package. But in some cases, it may be better to use the specialized functions directly. For example, if you're only interested in word segmentation, use [`FirstWord`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWord) or [`FirstWordInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWordInString):
|
||||||
|
|
||||||
|
```go
|
||||||
|
str := "Hello, world!"
|
||||||
|
state := -1
|
||||||
|
var c string
|
||||||
|
for len(str) > 0 {
|
||||||
|
c, str, state = uniseg.FirstWordInString(str, state)
|
||||||
|
fmt.Printf("(%s)\n", c)
|
||||||
|
}
|
||||||
|
// (Hello)
|
||||||
|
// (,)
|
||||||
|
// ( )
|
||||||
|
// (world)
|
||||||
|
// (!)
|
||||||
|
```
|
||||||
|
|
||||||
|
Similarly, use
|
||||||
|
|
||||||
|
- [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString) for grapheme cluster determination only,
|
||||||
|
- [`FirstSentence`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentence) or [`FirstSentenceInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentenceInString) for sentence segmentation only, and
|
||||||
|
- [`FirstLineSegment`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegment) or [`FirstLineSegmentInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegmentInString) for line breaking / word wrapping (although using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) is preferred as it will observe grapheme cluster boundaries).
|
||||||
|
|
||||||
|
If you're only interested in the width of characters, use [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString). It is much faster than using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step), [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString), or the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class because it does not include the logic for word / sentence / line boundaries.
|
||||||
|
|
||||||
|
Finally, if you need to reverse a string while preserving grapheme clusters, use [`ReverseString`](https://pkg.go.dev/github.com/rivo/uniseg#ReverseString):
|
||||||
|
|
||||||
|
```go
|
||||||
|
fmt.Println(uniseg.ReverseString("🇩🇪🏳️🌈"))
|
||||||
|
// 🏳️🌈🇩🇪
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Refer to https://pkg.go.dev/github.com/rivo/uniseg for the package's documentation.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
This package does not depend on any packages outside the standard library.
|
||||||
|
|
||||||
|
## Sponsor this Project
|
||||||
|
|
||||||
|
[Become a Sponsor on GitHub](https://github.com/sponsors/rivo?metadata_source=uniseg_readme) to support this project!
|
||||||
|
|
||||||
|
## Your Feedback
|
||||||
|
|
||||||
|
Add your issue here on GitHub, preferably before submitting any PR's. Feel free to get in touch if you have any questions.
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
Package uniseg implements Unicode Text Segmentation, Unicode Line Breaking, and
|
||||||
|
string width calculation for monospace fonts. Unicode Text Segmentation conforms
|
||||||
|
to Unicode Standard Annex #29 (https://unicode.org/reports/tr29/) and Unicode
|
||||||
|
Line Breaking conforms to Unicode Standard Annex #14
|
||||||
|
(https://unicode.org/reports/tr14/).
|
||||||
|
|
||||||
|
In short, using this package, you can split a string into grapheme clusters
|
||||||
|
(what people would usually refer to as a "character"), into words, and into
|
||||||
|
sentences. Or, in its simplest case, this package allows you to count the number
|
||||||
|
of characters in a string, especially when it contains complex characters such
|
||||||
|
as emojis, combining characters, or characters from Asian, Arabic, Hebrew, or
|
||||||
|
other languages. Additionally, you can use it to implement line breaking (or
|
||||||
|
"word wrapping"), that is, to determine where text can be broken over to the
|
||||||
|
next line when the width of the line is not big enough to fit the entire text.
|
||||||
|
Finally, you can use it to calculate the display width of a string for monospace
|
||||||
|
fonts.
|
||||||
|
|
||||||
|
# Getting Started
|
||||||
|
|
||||||
|
If you just want to count the number of characters in a string, you can use
|
||||||
|
[GraphemeClusterCount]. If you want to determine the display width of a string,
|
||||||
|
you can use [StringWidth]. If you want to iterate over a string, you can use
|
||||||
|
[Step], [StepString], or the [Graphemes] class (more convenient but less
|
||||||
|
performant). This will provide you with all information: grapheme clusters,
|
||||||
|
word boundaries, sentence boundaries, line breaks, and monospace character
|
||||||
|
widths. The specialized functions [FirstGraphemeCluster],
|
||||||
|
[FirstGraphemeClusterInString], [FirstWord], [FirstWordInString],
|
||||||
|
[FirstSentence], and [FirstSentenceInString] can be used if only one type of
|
||||||
|
information is needed.
|
||||||
|
|
||||||
|
# Grapheme Clusters
|
||||||
|
|
||||||
|
Consider the rainbow flag emoji: 🏳️🌈. On most modern systems, it appears as one
|
||||||
|
character. But its string representation actually has 14 bytes, so counting
|
||||||
|
bytes (or using len("🏳️🌈")) will not work as expected. Counting runes won't,
|
||||||
|
either: The flag has 4 Unicode code points, thus 4 runes. The stdlib function
|
||||||
|
utf8.RuneCountInString("🏳️🌈") and len([]rune("🏳️🌈")) will both return 4.
|
||||||
|
|
||||||
|
The [GraphemeClusterCount] function will return 1 for the rainbow flag emoji.
|
||||||
|
The Graphemes class and a variety of functions in this package will allow you to
|
||||||
|
split strings into its grapheme clusters.
|
||||||
|
|
||||||
|
# Word Boundaries
|
||||||
|
|
||||||
|
Word boundaries are used in a number of different contexts. The most familiar
|
||||||
|
ones are selection (double-click mouse selection), cursor movement ("move to
|
||||||
|
next word" control-arrow keys), and the dialog option "Whole Word Search" for
|
||||||
|
search and replace. This package provides methods for determining word
|
||||||
|
boundaries.
|
||||||
|
|
||||||
|
# Sentence Boundaries
|
||||||
|
|
||||||
|
Sentence boundaries are often used for triple-click or some other method of
|
||||||
|
selecting or iterating through blocks of text that are larger than single words.
|
||||||
|
They are also used to determine whether words occur within the same sentence in
|
||||||
|
database queries. This package provides methods for determining sentence
|
||||||
|
boundaries.
|
||||||
|
|
||||||
|
# Line Breaking
|
||||||
|
|
||||||
|
Line breaking, also known as word wrapping, is the process of breaking a section
|
||||||
|
of text into lines such that it will fit in the available width of a page,
|
||||||
|
window or other display area. This package provides methods to determine the
|
||||||
|
positions in a string where a line must be broken, may be broken, or must not be
|
||||||
|
broken.
|
||||||
|
|
||||||
|
# Monospace Width
|
||||||
|
|
||||||
|
Monospace width, as referred to in this package, is the width of a string in a
|
||||||
|
monospace font. This is commonly used in terminal user interfaces or text
|
||||||
|
displays or editors that don't support proportional fonts. A width of 1
|
||||||
|
corresponds to a single character cell. The C function [wcswidth()] and its
|
||||||
|
implementation in other programming languages is in widespread use for the same
|
||||||
|
purpose. However, there is no standard for the calculation of such widths, and
|
||||||
|
this package differs from wcswidth() in a number of ways, presumably to generate
|
||||||
|
more visually pleasing results.
|
||||||
|
|
||||||
|
To start, we assume that every code point has a width of 1, with the following
|
||||||
|
exceptions:
|
||||||
|
|
||||||
|
- Code points with grapheme cluster break properties Control, CR, LF, Extend,
|
||||||
|
and ZWJ have a width of 0.
|
||||||
|
- U+2E3A, Two-Em Dash, has a width of 3.
|
||||||
|
- U+2E3B, Three-Em Dash, has a width of 4.
|
||||||
|
- Characters with the East-Asian Width properties "Fullwidth" (F) and "Wide"
|
||||||
|
(W) have a width of 2. (Properties "Ambiguous" (A) and "Neutral" (N) both
|
||||||
|
have a width of 1.)
|
||||||
|
- Code points with grapheme cluster break property Regional Indicator have a
|
||||||
|
width of 2.
|
||||||
|
- Code points with grapheme cluster break property Extended Pictographic have
|
||||||
|
a width of 2, unless their Emoji Presentation flag is "No", in which case
|
||||||
|
the width is 1.
|
||||||
|
|
||||||
|
For Hangul grapheme clusters composed of conjoining Jamo and for Regional
|
||||||
|
Indicators (flags), all code points except the first one have a width of 0. For
|
||||||
|
grapheme clusters starting with an Extended Pictographic, any additional code
|
||||||
|
point will force a total width of 2, except if the Variation Selector-15
|
||||||
|
(U+FE0E) is included, in which case the total width is always 1. Grapheme
|
||||||
|
clusters ending with Variation Selector-16 (U+FE0F) have a width of 2.
|
||||||
|
|
||||||
|
Note that whether these widths appear correct depends on your application's
|
||||||
|
render engine, to which extent it conforms to the Unicode Standard, and its
|
||||||
|
choice of font.
|
||||||
|
|
||||||
|
[wcswidth()]: https://man7.org/linux/man-pages/man3/wcswidth.3.html
|
||||||
|
*/
|
||||||
|
package uniseg
|
2588
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/eastasianwidth.go
generated
vendored
Normal file
2588
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/eastasianwidth.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
295
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/emojipresentation.go
generated
vendored
Normal file
295
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/emojipresentation.go
generated
vendored
Normal file
|
@ -0,0 +1,295 @@
|
||||||
|
// Code generated via go generate from gen_properties.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
// emojiPresentation are taken from
|
||||||
|
//
|
||||||
|
// and
|
||||||
|
// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt
|
||||||
|
// ("Extended_Pictographic" only)
|
||||||
|
// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode
|
||||||
|
// license agreement.
|
||||||
|
var emojiPresentation = [][3]int{
|
||||||
|
{0x231A, 0x231B, prEmojiPresentation}, // E0.6 [2] (⌚..⌛) watch..hourglass done
|
||||||
|
{0x23E9, 0x23EC, prEmojiPresentation}, // E0.6 [4] (⏩..⏬) fast-forward button..fast down button
|
||||||
|
{0x23F0, 0x23F0, prEmojiPresentation}, // E0.6 [1] (⏰) alarm clock
|
||||||
|
{0x23F3, 0x23F3, prEmojiPresentation}, // E0.6 [1] (⏳) hourglass not done
|
||||||
|
{0x25FD, 0x25FE, prEmojiPresentation}, // E0.6 [2] (◽..◾) white medium-small square..black medium-small square
|
||||||
|
{0x2614, 0x2615, prEmojiPresentation}, // E0.6 [2] (☔..☕) umbrella with rain drops..hot beverage
|
||||||
|
{0x2648, 0x2653, prEmojiPresentation}, // E0.6 [12] (♈..♓) Aries..Pisces
|
||||||
|
{0x267F, 0x267F, prEmojiPresentation}, // E0.6 [1] (♿) wheelchair symbol
|
||||||
|
{0x2693, 0x2693, prEmojiPresentation}, // E0.6 [1] (⚓) anchor
|
||||||
|
{0x26A1, 0x26A1, prEmojiPresentation}, // E0.6 [1] (⚡) high voltage
|
||||||
|
{0x26AA, 0x26AB, prEmojiPresentation}, // E0.6 [2] (⚪..⚫) white circle..black circle
|
||||||
|
{0x26BD, 0x26BE, prEmojiPresentation}, // E0.6 [2] (⚽..⚾) soccer ball..baseball
|
||||||
|
{0x26C4, 0x26C5, prEmojiPresentation}, // E0.6 [2] (⛄..⛅) snowman without snow..sun behind cloud
|
||||||
|
{0x26CE, 0x26CE, prEmojiPresentation}, // E0.6 [1] (⛎) Ophiuchus
|
||||||
|
{0x26D4, 0x26D4, prEmojiPresentation}, // E0.6 [1] (⛔) no entry
|
||||||
|
{0x26EA, 0x26EA, prEmojiPresentation}, // E0.6 [1] (⛪) church
|
||||||
|
{0x26F2, 0x26F3, prEmojiPresentation}, // E0.6 [2] (⛲..⛳) fountain..flag in hole
|
||||||
|
{0x26F5, 0x26F5, prEmojiPresentation}, // E0.6 [1] (⛵) sailboat
|
||||||
|
{0x26FA, 0x26FA, prEmojiPresentation}, // E0.6 [1] (⛺) tent
|
||||||
|
{0x26FD, 0x26FD, prEmojiPresentation}, // E0.6 [1] (⛽) fuel pump
|
||||||
|
{0x2705, 0x2705, prEmojiPresentation}, // E0.6 [1] (✅) check mark button
|
||||||
|
{0x270A, 0x270B, prEmojiPresentation}, // E0.6 [2] (✊..✋) raised fist..raised hand
|
||||||
|
{0x2728, 0x2728, prEmojiPresentation}, // E0.6 [1] (✨) sparkles
|
||||||
|
{0x274C, 0x274C, prEmojiPresentation}, // E0.6 [1] (❌) cross mark
|
||||||
|
{0x274E, 0x274E, prEmojiPresentation}, // E0.6 [1] (❎) cross mark button
|
||||||
|
{0x2753, 0x2755, prEmojiPresentation}, // E0.6 [3] (❓..❕) red question mark..white exclamation mark
|
||||||
|
{0x2757, 0x2757, prEmojiPresentation}, // E0.6 [1] (❗) red exclamation mark
|
||||||
|
{0x2795, 0x2797, prEmojiPresentation}, // E0.6 [3] (➕..➗) plus..divide
|
||||||
|
{0x27B0, 0x27B0, prEmojiPresentation}, // E0.6 [1] (➰) curly loop
|
||||||
|
{0x27BF, 0x27BF, prEmojiPresentation}, // E1.0 [1] (➿) double curly loop
|
||||||
|
{0x2B1B, 0x2B1C, prEmojiPresentation}, // E0.6 [2] (⬛..⬜) black large square..white large square
|
||||||
|
{0x2B50, 0x2B50, prEmojiPresentation}, // E0.6 [1] (⭐) star
|
||||||
|
{0x2B55, 0x2B55, prEmojiPresentation}, // E0.6 [1] (⭕) hollow red circle
|
||||||
|
{0x1F004, 0x1F004, prEmojiPresentation}, // E0.6 [1] (🀄) mahjong red dragon
|
||||||
|
{0x1F0CF, 0x1F0CF, prEmojiPresentation}, // E0.6 [1] (🃏) joker
|
||||||
|
{0x1F18E, 0x1F18E, prEmojiPresentation}, // E0.6 [1] (🆎) AB button (blood type)
|
||||||
|
{0x1F191, 0x1F19A, prEmojiPresentation}, // E0.6 [10] (🆑..🆚) CL button..VS button
|
||||||
|
{0x1F1E6, 0x1F1FF, prEmojiPresentation}, // E0.0 [26] (🇦..🇿) regional indicator symbol letter a..regional indicator symbol letter z
|
||||||
|
{0x1F201, 0x1F201, prEmojiPresentation}, // E0.6 [1] (🈁) Japanese “here” button
|
||||||
|
{0x1F21A, 0x1F21A, prEmojiPresentation}, // E0.6 [1] (🈚) Japanese “free of charge” button
|
||||||
|
{0x1F22F, 0x1F22F, prEmojiPresentation}, // E0.6 [1] (🈯) Japanese “reserved” button
|
||||||
|
{0x1F232, 0x1F236, prEmojiPresentation}, // E0.6 [5] (🈲..🈶) Japanese “prohibited” button..Japanese “not free of charge” button
|
||||||
|
{0x1F238, 0x1F23A, prEmojiPresentation}, // E0.6 [3] (🈸..🈺) Japanese “application” button..Japanese “open for business” button
|
||||||
|
{0x1F250, 0x1F251, prEmojiPresentation}, // E0.6 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button
|
||||||
|
{0x1F300, 0x1F30C, prEmojiPresentation}, // E0.6 [13] (🌀..🌌) cyclone..milky way
|
||||||
|
{0x1F30D, 0x1F30E, prEmojiPresentation}, // E0.7 [2] (🌍..🌎) globe showing Europe-Africa..globe showing Americas
|
||||||
|
{0x1F30F, 0x1F30F, prEmojiPresentation}, // E0.6 [1] (🌏) globe showing Asia-Australia
|
||||||
|
{0x1F310, 0x1F310, prEmojiPresentation}, // E1.0 [1] (🌐) globe with meridians
|
||||||
|
{0x1F311, 0x1F311, prEmojiPresentation}, // E0.6 [1] (🌑) new moon
|
||||||
|
{0x1F312, 0x1F312, prEmojiPresentation}, // E1.0 [1] (🌒) waxing crescent moon
|
||||||
|
{0x1F313, 0x1F315, prEmojiPresentation}, // E0.6 [3] (🌓..🌕) first quarter moon..full moon
|
||||||
|
{0x1F316, 0x1F318, prEmojiPresentation}, // E1.0 [3] (🌖..🌘) waning gibbous moon..waning crescent moon
|
||||||
|
{0x1F319, 0x1F319, prEmojiPresentation}, // E0.6 [1] (🌙) crescent moon
|
||||||
|
{0x1F31A, 0x1F31A, prEmojiPresentation}, // E1.0 [1] (🌚) new moon face
|
||||||
|
{0x1F31B, 0x1F31B, prEmojiPresentation}, // E0.6 [1] (🌛) first quarter moon face
|
||||||
|
{0x1F31C, 0x1F31C, prEmojiPresentation}, // E0.7 [1] (🌜) last quarter moon face
|
||||||
|
{0x1F31D, 0x1F31E, prEmojiPresentation}, // E1.0 [2] (🌝..🌞) full moon face..sun with face
|
||||||
|
{0x1F31F, 0x1F320, prEmojiPresentation}, // E0.6 [2] (🌟..🌠) glowing star..shooting star
|
||||||
|
{0x1F32D, 0x1F32F, prEmojiPresentation}, // E1.0 [3] (🌭..🌯) hot dog..burrito
|
||||||
|
{0x1F330, 0x1F331, prEmojiPresentation}, // E0.6 [2] (🌰..🌱) chestnut..seedling
|
||||||
|
{0x1F332, 0x1F333, prEmojiPresentation}, // E1.0 [2] (🌲..🌳) evergreen tree..deciduous tree
|
||||||
|
{0x1F334, 0x1F335, prEmojiPresentation}, // E0.6 [2] (🌴..🌵) palm tree..cactus
|
||||||
|
{0x1F337, 0x1F34A, prEmojiPresentation}, // E0.6 [20] (🌷..🍊) tulip..tangerine
|
||||||
|
{0x1F34B, 0x1F34B, prEmojiPresentation}, // E1.0 [1] (🍋) lemon
|
||||||
|
{0x1F34C, 0x1F34F, prEmojiPresentation}, // E0.6 [4] (🍌..🍏) banana..green apple
|
||||||
|
{0x1F350, 0x1F350, prEmojiPresentation}, // E1.0 [1] (🍐) pear
|
||||||
|
{0x1F351, 0x1F37B, prEmojiPresentation}, // E0.6 [43] (🍑..🍻) peach..clinking beer mugs
|
||||||
|
{0x1F37C, 0x1F37C, prEmojiPresentation}, // E1.0 [1] (🍼) baby bottle
|
||||||
|
{0x1F37E, 0x1F37F, prEmojiPresentation}, // E1.0 [2] (🍾..🍿) bottle with popping cork..popcorn
|
||||||
|
{0x1F380, 0x1F393, prEmojiPresentation}, // E0.6 [20] (🎀..🎓) ribbon..graduation cap
|
||||||
|
{0x1F3A0, 0x1F3C4, prEmojiPresentation}, // E0.6 [37] (🎠..🏄) carousel horse..person surfing
|
||||||
|
{0x1F3C5, 0x1F3C5, prEmojiPresentation}, // E1.0 [1] (🏅) sports medal
|
||||||
|
{0x1F3C6, 0x1F3C6, prEmojiPresentation}, // E0.6 [1] (🏆) trophy
|
||||||
|
{0x1F3C7, 0x1F3C7, prEmojiPresentation}, // E1.0 [1] (🏇) horse racing
|
||||||
|
{0x1F3C8, 0x1F3C8, prEmojiPresentation}, // E0.6 [1] (🏈) american football
|
||||||
|
{0x1F3C9, 0x1F3C9, prEmojiPresentation}, // E1.0 [1] (🏉) rugby football
|
||||||
|
{0x1F3CA, 0x1F3CA, prEmojiPresentation}, // E0.6 [1] (🏊) person swimming
|
||||||
|
{0x1F3CF, 0x1F3D3, prEmojiPresentation}, // E1.0 [5] (🏏..🏓) cricket game..ping pong
|
||||||
|
{0x1F3E0, 0x1F3E3, prEmojiPresentation}, // E0.6 [4] (🏠..🏣) house..Japanese post office
|
||||||
|
{0x1F3E4, 0x1F3E4, prEmojiPresentation}, // E1.0 [1] (🏤) post office
|
||||||
|
{0x1F3E5, 0x1F3F0, prEmojiPresentation}, // E0.6 [12] (🏥..🏰) hospital..castle
|
||||||
|
{0x1F3F4, 0x1F3F4, prEmojiPresentation}, // E1.0 [1] (🏴) black flag
|
||||||
|
{0x1F3F8, 0x1F407, prEmojiPresentation}, // E1.0 [16] (🏸..🐇) badminton..rabbit
|
||||||
|
{0x1F408, 0x1F408, prEmojiPresentation}, // E0.7 [1] (🐈) cat
|
||||||
|
{0x1F409, 0x1F40B, prEmojiPresentation}, // E1.0 [3] (🐉..🐋) dragon..whale
|
||||||
|
{0x1F40C, 0x1F40E, prEmojiPresentation}, // E0.6 [3] (🐌..🐎) snail..horse
|
||||||
|
{0x1F40F, 0x1F410, prEmojiPresentation}, // E1.0 [2] (🐏..🐐) ram..goat
|
||||||
|
{0x1F411, 0x1F412, prEmojiPresentation}, // E0.6 [2] (🐑..🐒) ewe..monkey
|
||||||
|
{0x1F413, 0x1F413, prEmojiPresentation}, // E1.0 [1] (🐓) rooster
|
||||||
|
{0x1F414, 0x1F414, prEmojiPresentation}, // E0.6 [1] (🐔) chicken
|
||||||
|
{0x1F415, 0x1F415, prEmojiPresentation}, // E0.7 [1] (🐕) dog
|
||||||
|
{0x1F416, 0x1F416, prEmojiPresentation}, // E1.0 [1] (🐖) pig
|
||||||
|
{0x1F417, 0x1F429, prEmojiPresentation}, // E0.6 [19] (🐗..🐩) boar..poodle
|
||||||
|
{0x1F42A, 0x1F42A, prEmojiPresentation}, // E1.0 [1] (🐪) camel
|
||||||
|
{0x1F42B, 0x1F43E, prEmojiPresentation}, // E0.6 [20] (🐫..🐾) two-hump camel..paw prints
|
||||||
|
{0x1F440, 0x1F440, prEmojiPresentation}, // E0.6 [1] (👀) eyes
|
||||||
|
{0x1F442, 0x1F464, prEmojiPresentation}, // E0.6 [35] (👂..👤) ear..bust in silhouette
|
||||||
|
{0x1F465, 0x1F465, prEmojiPresentation}, // E1.0 [1] (👥) busts in silhouette
|
||||||
|
{0x1F466, 0x1F46B, prEmojiPresentation}, // E0.6 [6] (👦..👫) boy..woman and man holding hands
|
||||||
|
{0x1F46C, 0x1F46D, prEmojiPresentation}, // E1.0 [2] (👬..👭) men holding hands..women holding hands
|
||||||
|
{0x1F46E, 0x1F4AC, prEmojiPresentation}, // E0.6 [63] (👮..💬) police officer..speech balloon
|
||||||
|
{0x1F4AD, 0x1F4AD, prEmojiPresentation}, // E1.0 [1] (💭) thought balloon
|
||||||
|
{0x1F4AE, 0x1F4B5, prEmojiPresentation}, // E0.6 [8] (💮..💵) white flower..dollar banknote
|
||||||
|
{0x1F4B6, 0x1F4B7, prEmojiPresentation}, // E1.0 [2] (💶..💷) euro banknote..pound banknote
|
||||||
|
{0x1F4B8, 0x1F4EB, prEmojiPresentation}, // E0.6 [52] (💸..📫) money with wings..closed mailbox with raised flag
|
||||||
|
{0x1F4EC, 0x1F4ED, prEmojiPresentation}, // E0.7 [2] (📬..📭) open mailbox with raised flag..open mailbox with lowered flag
|
||||||
|
{0x1F4EE, 0x1F4EE, prEmojiPresentation}, // E0.6 [1] (📮) postbox
|
||||||
|
{0x1F4EF, 0x1F4EF, prEmojiPresentation}, // E1.0 [1] (📯) postal horn
|
||||||
|
{0x1F4F0, 0x1F4F4, prEmojiPresentation}, // E0.6 [5] (📰..📴) newspaper..mobile phone off
|
||||||
|
{0x1F4F5, 0x1F4F5, prEmojiPresentation}, // E1.0 [1] (📵) no mobile phones
|
||||||
|
{0x1F4F6, 0x1F4F7, prEmojiPresentation}, // E0.6 [2] (📶..📷) antenna bars..camera
|
||||||
|
{0x1F4F8, 0x1F4F8, prEmojiPresentation}, // E1.0 [1] (📸) camera with flash
|
||||||
|
{0x1F4F9, 0x1F4FC, prEmojiPresentation}, // E0.6 [4] (📹..📼) video camera..videocassette
|
||||||
|
{0x1F4FF, 0x1F502, prEmojiPresentation}, // E1.0 [4] (📿..🔂) prayer beads..repeat single button
|
||||||
|
{0x1F503, 0x1F503, prEmojiPresentation}, // E0.6 [1] (🔃) clockwise vertical arrows
|
||||||
|
{0x1F504, 0x1F507, prEmojiPresentation}, // E1.0 [4] (🔄..🔇) counterclockwise arrows button..muted speaker
|
||||||
|
{0x1F508, 0x1F508, prEmojiPresentation}, // E0.7 [1] (🔈) speaker low volume
|
||||||
|
{0x1F509, 0x1F509, prEmojiPresentation}, // E1.0 [1] (🔉) speaker medium volume
|
||||||
|
{0x1F50A, 0x1F514, prEmojiPresentation}, // E0.6 [11] (🔊..🔔) speaker high volume..bell
|
||||||
|
{0x1F515, 0x1F515, prEmojiPresentation}, // E1.0 [1] (🔕) bell with slash
|
||||||
|
{0x1F516, 0x1F52B, prEmojiPresentation}, // E0.6 [22] (🔖..🔫) bookmark..water pistol
|
||||||
|
{0x1F52C, 0x1F52D, prEmojiPresentation}, // E1.0 [2] (🔬..🔭) microscope..telescope
|
||||||
|
{0x1F52E, 0x1F53D, prEmojiPresentation}, // E0.6 [16] (🔮..🔽) crystal ball..downwards button
|
||||||
|
{0x1F54B, 0x1F54E, prEmojiPresentation}, // E1.0 [4] (🕋..🕎) kaaba..menorah
|
||||||
|
{0x1F550, 0x1F55B, prEmojiPresentation}, // E0.6 [12] (🕐..🕛) one o’clock..twelve o’clock
|
||||||
|
{0x1F55C, 0x1F567, prEmojiPresentation}, // E0.7 [12] (🕜..🕧) one-thirty..twelve-thirty
|
||||||
|
{0x1F57A, 0x1F57A, prEmojiPresentation}, // E3.0 [1] (🕺) man dancing
|
||||||
|
{0x1F595, 0x1F596, prEmojiPresentation}, // E1.0 [2] (🖕..🖖) middle finger..vulcan salute
|
||||||
|
{0x1F5A4, 0x1F5A4, prEmojiPresentation}, // E3.0 [1] (🖤) black heart
|
||||||
|
{0x1F5FB, 0x1F5FF, prEmojiPresentation}, // E0.6 [5] (🗻..🗿) mount fuji..moai
|
||||||
|
{0x1F600, 0x1F600, prEmojiPresentation}, // E1.0 [1] (😀) grinning face
|
||||||
|
{0x1F601, 0x1F606, prEmojiPresentation}, // E0.6 [6] (😁..😆) beaming face with smiling eyes..grinning squinting face
|
||||||
|
{0x1F607, 0x1F608, prEmojiPresentation}, // E1.0 [2] (😇..😈) smiling face with halo..smiling face with horns
|
||||||
|
{0x1F609, 0x1F60D, prEmojiPresentation}, // E0.6 [5] (😉..😍) winking face..smiling face with heart-eyes
|
||||||
|
{0x1F60E, 0x1F60E, prEmojiPresentation}, // E1.0 [1] (😎) smiling face with sunglasses
|
||||||
|
{0x1F60F, 0x1F60F, prEmojiPresentation}, // E0.6 [1] (😏) smirking face
|
||||||
|
{0x1F610, 0x1F610, prEmojiPresentation}, // E0.7 [1] (😐) neutral face
|
||||||
|
{0x1F611, 0x1F611, prEmojiPresentation}, // E1.0 [1] (😑) expressionless face
|
||||||
|
{0x1F612, 0x1F614, prEmojiPresentation}, // E0.6 [3] (😒..😔) unamused face..pensive face
|
||||||
|
{0x1F615, 0x1F615, prEmojiPresentation}, // E1.0 [1] (😕) confused face
|
||||||
|
{0x1F616, 0x1F616, prEmojiPresentation}, // E0.6 [1] (😖) confounded face
|
||||||
|
{0x1F617, 0x1F617, prEmojiPresentation}, // E1.0 [1] (😗) kissing face
|
||||||
|
{0x1F618, 0x1F618, prEmojiPresentation}, // E0.6 [1] (😘) face blowing a kiss
|
||||||
|
{0x1F619, 0x1F619, prEmojiPresentation}, // E1.0 [1] (😙) kissing face with smiling eyes
|
||||||
|
{0x1F61A, 0x1F61A, prEmojiPresentation}, // E0.6 [1] (😚) kissing face with closed eyes
|
||||||
|
{0x1F61B, 0x1F61B, prEmojiPresentation}, // E1.0 [1] (😛) face with tongue
|
||||||
|
{0x1F61C, 0x1F61E, prEmojiPresentation}, // E0.6 [3] (😜..😞) winking face with tongue..disappointed face
|
||||||
|
{0x1F61F, 0x1F61F, prEmojiPresentation}, // E1.0 [1] (😟) worried face
|
||||||
|
{0x1F620, 0x1F625, prEmojiPresentation}, // E0.6 [6] (😠..😥) angry face..sad but relieved face
|
||||||
|
{0x1F626, 0x1F627, prEmojiPresentation}, // E1.0 [2] (😦..😧) frowning face with open mouth..anguished face
|
||||||
|
{0x1F628, 0x1F62B, prEmojiPresentation}, // E0.6 [4] (😨..😫) fearful face..tired face
|
||||||
|
{0x1F62C, 0x1F62C, prEmojiPresentation}, // E1.0 [1] (😬) grimacing face
|
||||||
|
{0x1F62D, 0x1F62D, prEmojiPresentation}, // E0.6 [1] (😭) loudly crying face
|
||||||
|
{0x1F62E, 0x1F62F, prEmojiPresentation}, // E1.0 [2] (😮..😯) face with open mouth..hushed face
|
||||||
|
{0x1F630, 0x1F633, prEmojiPresentation}, // E0.6 [4] (😰..😳) anxious face with sweat..flushed face
|
||||||
|
{0x1F634, 0x1F634, prEmojiPresentation}, // E1.0 [1] (😴) sleeping face
|
||||||
|
{0x1F635, 0x1F635, prEmojiPresentation}, // E0.6 [1] (😵) face with crossed-out eyes
|
||||||
|
{0x1F636, 0x1F636, prEmojiPresentation}, // E1.0 [1] (😶) face without mouth
|
||||||
|
{0x1F637, 0x1F640, prEmojiPresentation}, // E0.6 [10] (😷..🙀) face with medical mask..weary cat
|
||||||
|
{0x1F641, 0x1F644, prEmojiPresentation}, // E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes
|
||||||
|
{0x1F645, 0x1F64F, prEmojiPresentation}, // E0.6 [11] (🙅..🙏) person gesturing NO..folded hands
|
||||||
|
{0x1F680, 0x1F680, prEmojiPresentation}, // E0.6 [1] (🚀) rocket
|
||||||
|
{0x1F681, 0x1F682, prEmojiPresentation}, // E1.0 [2] (🚁..🚂) helicopter..locomotive
|
||||||
|
{0x1F683, 0x1F685, prEmojiPresentation}, // E0.6 [3] (🚃..🚅) railway car..bullet train
|
||||||
|
{0x1F686, 0x1F686, prEmojiPresentation}, // E1.0 [1] (🚆) train
|
||||||
|
{0x1F687, 0x1F687, prEmojiPresentation}, // E0.6 [1] (🚇) metro
|
||||||
|
{0x1F688, 0x1F688, prEmojiPresentation}, // E1.0 [1] (🚈) light rail
|
||||||
|
{0x1F689, 0x1F689, prEmojiPresentation}, // E0.6 [1] (🚉) station
|
||||||
|
{0x1F68A, 0x1F68B, prEmojiPresentation}, // E1.0 [2] (🚊..🚋) tram..tram car
|
||||||
|
{0x1F68C, 0x1F68C, prEmojiPresentation}, // E0.6 [1] (🚌) bus
|
||||||
|
{0x1F68D, 0x1F68D, prEmojiPresentation}, // E0.7 [1] (🚍) oncoming bus
|
||||||
|
{0x1F68E, 0x1F68E, prEmojiPresentation}, // E1.0 [1] (🚎) trolleybus
|
||||||
|
{0x1F68F, 0x1F68F, prEmojiPresentation}, // E0.6 [1] (🚏) bus stop
|
||||||
|
{0x1F690, 0x1F690, prEmojiPresentation}, // E1.0 [1] (🚐) minibus
|
||||||
|
{0x1F691, 0x1F693, prEmojiPresentation}, // E0.6 [3] (🚑..🚓) ambulance..police car
|
||||||
|
{0x1F694, 0x1F694, prEmojiPresentation}, // E0.7 [1] (🚔) oncoming police car
|
||||||
|
{0x1F695, 0x1F695, prEmojiPresentation}, // E0.6 [1] (🚕) taxi
|
||||||
|
{0x1F696, 0x1F696, prEmojiPresentation}, // E1.0 [1] (🚖) oncoming taxi
|
||||||
|
{0x1F697, 0x1F697, prEmojiPresentation}, // E0.6 [1] (🚗) automobile
|
||||||
|
{0x1F698, 0x1F698, prEmojiPresentation}, // E0.7 [1] (🚘) oncoming automobile
|
||||||
|
{0x1F699, 0x1F69A, prEmojiPresentation}, // E0.6 [2] (🚙..🚚) sport utility vehicle..delivery truck
|
||||||
|
{0x1F69B, 0x1F6A1, prEmojiPresentation}, // E1.0 [7] (🚛..🚡) articulated lorry..aerial tramway
|
||||||
|
{0x1F6A2, 0x1F6A2, prEmojiPresentation}, // E0.6 [1] (🚢) ship
|
||||||
|
{0x1F6A3, 0x1F6A3, prEmojiPresentation}, // E1.0 [1] (🚣) person rowing boat
|
||||||
|
{0x1F6A4, 0x1F6A5, prEmojiPresentation}, // E0.6 [2] (🚤..🚥) speedboat..horizontal traffic light
|
||||||
|
{0x1F6A6, 0x1F6A6, prEmojiPresentation}, // E1.0 [1] (🚦) vertical traffic light
|
||||||
|
{0x1F6A7, 0x1F6AD, prEmojiPresentation}, // E0.6 [7] (🚧..🚭) construction..no smoking
|
||||||
|
{0x1F6AE, 0x1F6B1, prEmojiPresentation}, // E1.0 [4] (🚮..🚱) litter in bin sign..non-potable water
|
||||||
|
{0x1F6B2, 0x1F6B2, prEmojiPresentation}, // E0.6 [1] (🚲) bicycle
|
||||||
|
{0x1F6B3, 0x1F6B5, prEmojiPresentation}, // E1.0 [3] (🚳..🚵) no bicycles..person mountain biking
|
||||||
|
{0x1F6B6, 0x1F6B6, prEmojiPresentation}, // E0.6 [1] (🚶) person walking
|
||||||
|
{0x1F6B7, 0x1F6B8, prEmojiPresentation}, // E1.0 [2] (🚷..🚸) no pedestrians..children crossing
|
||||||
|
{0x1F6B9, 0x1F6BE, prEmojiPresentation}, // E0.6 [6] (🚹..🚾) men’s room..water closet
|
||||||
|
{0x1F6BF, 0x1F6BF, prEmojiPresentation}, // E1.0 [1] (🚿) shower
|
||||||
|
{0x1F6C0, 0x1F6C0, prEmojiPresentation}, // E0.6 [1] (🛀) person taking bath
|
||||||
|
{0x1F6C1, 0x1F6C5, prEmojiPresentation}, // E1.0 [5] (🛁..🛅) bathtub..left luggage
|
||||||
|
{0x1F6CC, 0x1F6CC, prEmojiPresentation}, // E1.0 [1] (🛌) person in bed
|
||||||
|
{0x1F6D0, 0x1F6D0, prEmojiPresentation}, // E1.0 [1] (🛐) place of worship
|
||||||
|
{0x1F6D1, 0x1F6D2, prEmojiPresentation}, // E3.0 [2] (🛑..🛒) stop sign..shopping cart
|
||||||
|
{0x1F6D5, 0x1F6D5, prEmojiPresentation}, // E12.0 [1] (🛕) hindu temple
|
||||||
|
{0x1F6D6, 0x1F6D7, prEmojiPresentation}, // E13.0 [2] (🛖..🛗) hut..elevator
|
||||||
|
{0x1F6DC, 0x1F6DC, prEmojiPresentation}, // E15.0 [1] (🛜) wireless
|
||||||
|
{0x1F6DD, 0x1F6DF, prEmojiPresentation}, // E14.0 [3] (🛝..🛟) playground slide..ring buoy
|
||||||
|
{0x1F6EB, 0x1F6EC, prEmojiPresentation}, // E1.0 [2] (🛫..🛬) airplane departure..airplane arrival
|
||||||
|
{0x1F6F4, 0x1F6F6, prEmojiPresentation}, // E3.0 [3] (🛴..🛶) kick scooter..canoe
|
||||||
|
{0x1F6F7, 0x1F6F8, prEmojiPresentation}, // E5.0 [2] (🛷..🛸) sled..flying saucer
|
||||||
|
{0x1F6F9, 0x1F6F9, prEmojiPresentation}, // E11.0 [1] (🛹) skateboard
|
||||||
|
{0x1F6FA, 0x1F6FA, prEmojiPresentation}, // E12.0 [1] (🛺) auto rickshaw
|
||||||
|
{0x1F6FB, 0x1F6FC, prEmojiPresentation}, // E13.0 [2] (🛻..🛼) pickup truck..roller skate
|
||||||
|
{0x1F7E0, 0x1F7EB, prEmojiPresentation}, // E12.0 [12] (🟠..🟫) orange circle..brown square
|
||||||
|
{0x1F7F0, 0x1F7F0, prEmojiPresentation}, // E14.0 [1] (🟰) heavy equals sign
|
||||||
|
{0x1F90C, 0x1F90C, prEmojiPresentation}, // E13.0 [1] (🤌) pinched fingers
|
||||||
|
{0x1F90D, 0x1F90F, prEmojiPresentation}, // E12.0 [3] (🤍..🤏) white heart..pinching hand
|
||||||
|
{0x1F910, 0x1F918, prEmojiPresentation}, // E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns
|
||||||
|
{0x1F919, 0x1F91E, prEmojiPresentation}, // E3.0 [6] (🤙..🤞) call me hand..crossed fingers
|
||||||
|
{0x1F91F, 0x1F91F, prEmojiPresentation}, // E5.0 [1] (🤟) love-you gesture
|
||||||
|
{0x1F920, 0x1F927, prEmojiPresentation}, // E3.0 [8] (🤠..🤧) cowboy hat face..sneezing face
|
||||||
|
{0x1F928, 0x1F92F, prEmojiPresentation}, // E5.0 [8] (🤨..🤯) face with raised eyebrow..exploding head
|
||||||
|
{0x1F930, 0x1F930, prEmojiPresentation}, // E3.0 [1] (🤰) pregnant woman
|
||||||
|
{0x1F931, 0x1F932, prEmojiPresentation}, // E5.0 [2] (🤱..🤲) breast-feeding..palms up together
|
||||||
|
{0x1F933, 0x1F93A, prEmojiPresentation}, // E3.0 [8] (🤳..🤺) selfie..person fencing
|
||||||
|
{0x1F93C, 0x1F93E, prEmojiPresentation}, // E3.0 [3] (🤼..🤾) people wrestling..person playing handball
|
||||||
|
{0x1F93F, 0x1F93F, prEmojiPresentation}, // E12.0 [1] (🤿) diving mask
|
||||||
|
{0x1F940, 0x1F945, prEmojiPresentation}, // E3.0 [6] (🥀..🥅) wilted flower..goal net
|
||||||
|
{0x1F947, 0x1F94B, prEmojiPresentation}, // E3.0 [5] (🥇..🥋) 1st place medal..martial arts uniform
|
||||||
|
{0x1F94C, 0x1F94C, prEmojiPresentation}, // E5.0 [1] (🥌) curling stone
|
||||||
|
{0x1F94D, 0x1F94F, prEmojiPresentation}, // E11.0 [3] (🥍..🥏) lacrosse..flying disc
|
||||||
|
{0x1F950, 0x1F95E, prEmojiPresentation}, // E3.0 [15] (🥐..🥞) croissant..pancakes
|
||||||
|
{0x1F95F, 0x1F96B, prEmojiPresentation}, // E5.0 [13] (🥟..🥫) dumpling..canned food
|
||||||
|
{0x1F96C, 0x1F970, prEmojiPresentation}, // E11.0 [5] (🥬..🥰) leafy green..smiling face with hearts
|
||||||
|
{0x1F971, 0x1F971, prEmojiPresentation}, // E12.0 [1] (🥱) yawning face
|
||||||
|
{0x1F972, 0x1F972, prEmojiPresentation}, // E13.0 [1] (🥲) smiling face with tear
|
||||||
|
{0x1F973, 0x1F976, prEmojiPresentation}, // E11.0 [4] (🥳..🥶) partying face..cold face
|
||||||
|
{0x1F977, 0x1F978, prEmojiPresentation}, // E13.0 [2] (🥷..🥸) ninja..disguised face
|
||||||
|
{0x1F979, 0x1F979, prEmojiPresentation}, // E14.0 [1] (🥹) face holding back tears
|
||||||
|
{0x1F97A, 0x1F97A, prEmojiPresentation}, // E11.0 [1] (🥺) pleading face
|
||||||
|
{0x1F97B, 0x1F97B, prEmojiPresentation}, // E12.0 [1] (🥻) sari
|
||||||
|
{0x1F97C, 0x1F97F, prEmojiPresentation}, // E11.0 [4] (🥼..🥿) lab coat..flat shoe
|
||||||
|
{0x1F980, 0x1F984, prEmojiPresentation}, // E1.0 [5] (🦀..🦄) crab..unicorn
|
||||||
|
{0x1F985, 0x1F991, prEmojiPresentation}, // E3.0 [13] (🦅..🦑) eagle..squid
|
||||||
|
{0x1F992, 0x1F997, prEmojiPresentation}, // E5.0 [6] (🦒..🦗) giraffe..cricket
|
||||||
|
{0x1F998, 0x1F9A2, prEmojiPresentation}, // E11.0 [11] (🦘..🦢) kangaroo..swan
|
||||||
|
{0x1F9A3, 0x1F9A4, prEmojiPresentation}, // E13.0 [2] (🦣..🦤) mammoth..dodo
|
||||||
|
{0x1F9A5, 0x1F9AA, prEmojiPresentation}, // E12.0 [6] (🦥..🦪) sloth..oyster
|
||||||
|
{0x1F9AB, 0x1F9AD, prEmojiPresentation}, // E13.0 [3] (🦫..🦭) beaver..seal
|
||||||
|
{0x1F9AE, 0x1F9AF, prEmojiPresentation}, // E12.0 [2] (🦮..🦯) guide dog..white cane
|
||||||
|
{0x1F9B0, 0x1F9B9, prEmojiPresentation}, // E11.0 [10] (🦰..🦹) red hair..supervillain
|
||||||
|
{0x1F9BA, 0x1F9BF, prEmojiPresentation}, // E12.0 [6] (🦺..🦿) safety vest..mechanical leg
|
||||||
|
{0x1F9C0, 0x1F9C0, prEmojiPresentation}, // E1.0 [1] (🧀) cheese wedge
|
||||||
|
{0x1F9C1, 0x1F9C2, prEmojiPresentation}, // E11.0 [2] (🧁..🧂) cupcake..salt
|
||||||
|
{0x1F9C3, 0x1F9CA, prEmojiPresentation}, // E12.0 [8] (🧃..🧊) beverage box..ice
|
||||||
|
{0x1F9CB, 0x1F9CB, prEmojiPresentation}, // E13.0 [1] (🧋) bubble tea
|
||||||
|
{0x1F9CC, 0x1F9CC, prEmojiPresentation}, // E14.0 [1] (🧌) troll
|
||||||
|
{0x1F9CD, 0x1F9CF, prEmojiPresentation}, // E12.0 [3] (🧍..🧏) person standing..deaf person
|
||||||
|
{0x1F9D0, 0x1F9E6, prEmojiPresentation}, // E5.0 [23] (🧐..🧦) face with monocle..socks
|
||||||
|
{0x1F9E7, 0x1F9FF, prEmojiPresentation}, // E11.0 [25] (🧧..🧿) red envelope..nazar amulet
|
||||||
|
{0x1FA70, 0x1FA73, prEmojiPresentation}, // E12.0 [4] (🩰..🩳) ballet shoes..shorts
|
||||||
|
{0x1FA74, 0x1FA74, prEmojiPresentation}, // E13.0 [1] (🩴) thong sandal
|
||||||
|
{0x1FA75, 0x1FA77, prEmojiPresentation}, // E15.0 [3] (🩵..🩷) light blue heart..pink heart
|
||||||
|
{0x1FA78, 0x1FA7A, prEmojiPresentation}, // E12.0 [3] (🩸..🩺) drop of blood..stethoscope
|
||||||
|
{0x1FA7B, 0x1FA7C, prEmojiPresentation}, // E14.0 [2] (🩻..🩼) x-ray..crutch
|
||||||
|
{0x1FA80, 0x1FA82, prEmojiPresentation}, // E12.0 [3] (🪀..🪂) yo-yo..parachute
|
||||||
|
{0x1FA83, 0x1FA86, prEmojiPresentation}, // E13.0 [4] (🪃..🪆) boomerang..nesting dolls
|
||||||
|
{0x1FA87, 0x1FA88, prEmojiPresentation}, // E15.0 [2] (🪇..🪈) maracas..flute
|
||||||
|
{0x1FA90, 0x1FA95, prEmojiPresentation}, // E12.0 [6] (🪐..🪕) ringed planet..banjo
|
||||||
|
{0x1FA96, 0x1FAA8, prEmojiPresentation}, // E13.0 [19] (🪖..🪨) military helmet..rock
|
||||||
|
{0x1FAA9, 0x1FAAC, prEmojiPresentation}, // E14.0 [4] (🪩..🪬) mirror ball..hamsa
|
||||||
|
{0x1FAAD, 0x1FAAF, prEmojiPresentation}, // E15.0 [3] (🪭..🪯) folding hand fan..khanda
|
||||||
|
{0x1FAB0, 0x1FAB6, prEmojiPresentation}, // E13.0 [7] (🪰..🪶) fly..feather
|
||||||
|
{0x1FAB7, 0x1FABA, prEmojiPresentation}, // E14.0 [4] (🪷..🪺) lotus..nest with eggs
|
||||||
|
{0x1FABB, 0x1FABD, prEmojiPresentation}, // E15.0 [3] (🪻..🪽) hyacinth..wing
|
||||||
|
{0x1FABF, 0x1FABF, prEmojiPresentation}, // E15.0 [1] (🪿) goose
|
||||||
|
{0x1FAC0, 0x1FAC2, prEmojiPresentation}, // E13.0 [3] (🫀..🫂) anatomical heart..people hugging
|
||||||
|
{0x1FAC3, 0x1FAC5, prEmojiPresentation}, // E14.0 [3] (🫃..🫅) pregnant man..person with crown
|
||||||
|
{0x1FACE, 0x1FACF, prEmojiPresentation}, // E15.0 [2] (🫎..🫏) moose..donkey
|
||||||
|
{0x1FAD0, 0x1FAD6, prEmojiPresentation}, // E13.0 [7] (🫐..🫖) blueberries..teapot
|
||||||
|
{0x1FAD7, 0x1FAD9, prEmojiPresentation}, // E14.0 [3] (🫗..🫙) pouring liquid..jar
|
||||||
|
{0x1FADA, 0x1FADB, prEmojiPresentation}, // E15.0 [2] (🫚..🫛) ginger root..pea pod
|
||||||
|
{0x1FAE0, 0x1FAE7, prEmojiPresentation}, // E14.0 [8] (🫠..🫧) melting face..bubbles
|
||||||
|
{0x1FAE8, 0x1FAE8, prEmojiPresentation}, // E15.0 [1] (🫨) shaking face
|
||||||
|
{0x1FAF0, 0x1FAF6, prEmojiPresentation}, // E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands
|
||||||
|
{0x1FAF7, 0x1FAF8, prEmojiPresentation}, // E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand
|
||||||
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
//go:build generate
|
||||||
|
|
||||||
|
// This program generates a Go containing a slice of test cases based on the
|
||||||
|
// Unicode Character Database auxiliary data files. The command line arguments
|
||||||
|
// are as follows:
|
||||||
|
//
|
||||||
|
// 1. The name of the Unicode data file (just the filename, without extension).
|
||||||
|
// 2. The name of the locally generated Go file.
|
||||||
|
// 3. The name of the slice containing the test cases.
|
||||||
|
// 4. The name of the generator, for logging purposes.
|
||||||
|
//
|
||||||
|
//go:generate go run gen_breaktest.go GraphemeBreakTest graphemebreak_test.go graphemeBreakTestCases graphemes
|
||||||
|
//go:generate go run gen_breaktest.go WordBreakTest wordbreak_test.go wordBreakTestCases words
|
||||||
|
//go:generate go run gen_breaktest.go SentenceBreakTest sentencebreak_test.go sentenceBreakTestCases sentences
|
||||||
|
//go:generate go run gen_breaktest.go LineBreakTest linebreak_test.go lineBreakTestCases lines
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"go/format"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// We want to test against a specific version rather than the latest. When the
|
||||||
|
// package is upgraded to a new version, change these to generate new tests.
|
||||||
|
const (
|
||||||
|
testCaseURL = `https://www.unicode.org/Public/15.0.0/ucd/auxiliary/%s.txt`
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 5 {
|
||||||
|
fmt.Println("Not enough arguments, see code for details")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.SetPrefix("gen_breaktest (" + os.Args[4] + "): ")
|
||||||
|
log.SetFlags(0)
|
||||||
|
|
||||||
|
// Read text of testcases and parse into Go source code.
|
||||||
|
src, err := parse(fmt.Sprintf(testCaseURL, os.Args[1]))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the Go code.
|
||||||
|
formatted, err := format.Source(src)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("gofmt:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write it out.
|
||||||
|
log.Print("Writing to ", os.Args[2])
|
||||||
|
if err := ioutil.WriteFile(os.Args[2], formatted, 0644); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse reads a break text file, either from a local file or from a URL. It
|
||||||
|
// parses the file data into Go source code representing the test cases.
|
||||||
|
func parse(url string) ([]byte, error) {
|
||||||
|
log.Printf("Parsing %s", url)
|
||||||
|
res, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body := res.Body
|
||||||
|
defer body.Close()
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
buf.Grow(120 << 10)
|
||||||
|
buf.WriteString(`// Code generated via go generate from gen_breaktest.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
// ` + os.Args[3] + ` are Grapheme testcases taken from
|
||||||
|
// ` + url + `
|
||||||
|
// on ` + time.Now().Format("January 2, 2006") + `. See
|
||||||
|
// https://www.unicode.org/license.html for the Unicode license agreement.
|
||||||
|
var ` + os.Args[3] + ` = []testCase {
|
||||||
|
`)
|
||||||
|
|
||||||
|
sc := bufio.NewScanner(body)
|
||||||
|
num := 1
|
||||||
|
var line []byte
|
||||||
|
original := make([]byte, 0, 64)
|
||||||
|
expected := make([]byte, 0, 64)
|
||||||
|
for sc.Scan() {
|
||||||
|
num++
|
||||||
|
line = sc.Bytes()
|
||||||
|
if len(line) == 0 || line[0] == '#' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var comment []byte
|
||||||
|
if i := bytes.IndexByte(line, '#'); i >= 0 {
|
||||||
|
comment = bytes.TrimSpace(line[i+1:])
|
||||||
|
line = bytes.TrimSpace(line[:i])
|
||||||
|
}
|
||||||
|
original, expected, err := parseRuneSequence(line, original[:0], expected[:0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(`line %d: %v: %q`, num, err, line)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(buf, "\t{original: \"%s\", expected: %s}, // %s\n", original, expected, comment)
|
||||||
|
}
|
||||||
|
if err := sc.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for final "# EOF", useful check if we're streaming via HTTP
|
||||||
|
if !bytes.Equal(line, []byte("# EOF")) {
|
||||||
|
return nil, fmt.Errorf(`line %d: exected "# EOF" as final line, got %q`, num, line)
|
||||||
|
}
|
||||||
|
buf.WriteString("}\n")
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by parseRuneSequence to match input via bytes.HasPrefix.
|
||||||
|
var (
|
||||||
|
prefixBreak = []byte("÷ ")
|
||||||
|
prefixDontBreak = []byte("× ")
|
||||||
|
breakOk = []byte("÷")
|
||||||
|
breakNo = []byte("×")
|
||||||
|
)
|
||||||
|
|
||||||
|
// parseRuneSequence parses a rune + breaking opportunity sequence from b
|
||||||
|
// and appends the Go code for testcase.original to orig
|
||||||
|
// and appends the Go code for testcase.expected to exp.
|
||||||
|
// It retuns the new orig and exp slices.
|
||||||
|
//
|
||||||
|
// E.g. for the input b="÷ 0020 × 0308 ÷ 1F1E6 ÷"
|
||||||
|
// it will append
|
||||||
|
//
|
||||||
|
// "\u0020\u0308\U0001F1E6"
|
||||||
|
//
|
||||||
|
// and "[][]rune{{0x0020,0x0308},{0x1F1E6},}"
|
||||||
|
// to orig and exp respectively.
|
||||||
|
//
|
||||||
|
// The formatting of exp is expected to be cleaned up by gofmt or format.Source.
|
||||||
|
// Note we explicitly require the sequence to start with ÷ and we implicitly
|
||||||
|
// require it to end with ÷.
|
||||||
|
func parseRuneSequence(b, orig, exp []byte) ([]byte, []byte, error) {
|
||||||
|
// Check for and remove first ÷ or ×.
|
||||||
|
if !bytes.HasPrefix(b, prefixBreak) && !bytes.HasPrefix(b, prefixDontBreak) {
|
||||||
|
return nil, nil, errors.New("expected ÷ or × as first character")
|
||||||
|
}
|
||||||
|
if bytes.HasPrefix(b, prefixBreak) {
|
||||||
|
b = b[len(prefixBreak):]
|
||||||
|
} else {
|
||||||
|
b = b[len(prefixDontBreak):]
|
||||||
|
}
|
||||||
|
|
||||||
|
boundary := true
|
||||||
|
exp = append(exp, "[][]rune{"...)
|
||||||
|
for len(b) > 0 {
|
||||||
|
if boundary {
|
||||||
|
exp = append(exp, '{')
|
||||||
|
}
|
||||||
|
exp = append(exp, "0x"...)
|
||||||
|
// Find end of hex digits.
|
||||||
|
var i int
|
||||||
|
for i = 0; i < len(b) && b[i] != ' '; i++ {
|
||||||
|
if d := b[i]; ('0' <= d || d <= '9') ||
|
||||||
|
('A' <= d || d <= 'F') ||
|
||||||
|
('a' <= d || d <= 'f') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, nil, errors.New("bad hex digit")
|
||||||
|
}
|
||||||
|
switch i {
|
||||||
|
case 4:
|
||||||
|
orig = append(orig, "\\u"...)
|
||||||
|
case 5:
|
||||||
|
orig = append(orig, "\\U000"...)
|
||||||
|
default:
|
||||||
|
return nil, nil, errors.New("unsupport code point hex length")
|
||||||
|
}
|
||||||
|
orig = append(orig, b[:i]...)
|
||||||
|
exp = append(exp, b[:i]...)
|
||||||
|
b = b[i:]
|
||||||
|
|
||||||
|
// Check for space between hex and ÷ or ×.
|
||||||
|
if len(b) < 1 || b[0] != ' ' {
|
||||||
|
return nil, nil, errors.New("bad input")
|
||||||
|
}
|
||||||
|
b = b[1:]
|
||||||
|
|
||||||
|
// Check for next boundary.
|
||||||
|
switch {
|
||||||
|
case bytes.HasPrefix(b, breakOk):
|
||||||
|
boundary = true
|
||||||
|
b = b[len(breakOk):]
|
||||||
|
case bytes.HasPrefix(b, breakNo):
|
||||||
|
boundary = false
|
||||||
|
b = b[len(breakNo):]
|
||||||
|
default:
|
||||||
|
return nil, nil, errors.New("missing ÷ or ×")
|
||||||
|
}
|
||||||
|
if boundary {
|
||||||
|
exp = append(exp, '}')
|
||||||
|
}
|
||||||
|
exp = append(exp, ',')
|
||||||
|
if len(b) > 0 && b[0] == ' ' {
|
||||||
|
b = b[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exp = append(exp, '}')
|
||||||
|
return orig, exp, nil
|
||||||
|
}
|
|
@ -0,0 +1,261 @@
|
||||||
|
//go:build generate
|
||||||
|
|
||||||
|
// This program generates a property file in Go file from Unicode Character
|
||||||
|
// Database auxiliary data files. The command line arguments are as follows:
|
||||||
|
//
|
||||||
|
// 1. The name of the Unicode data file (just the filename, without extension).
|
||||||
|
// Can be "-" (to skip) if the emoji flag is included.
|
||||||
|
// 2. The name of the locally generated Go file.
|
||||||
|
// 3. The name of the slice mapping code points to properties.
|
||||||
|
// 4. The name of the generator, for logging purposes.
|
||||||
|
// 5. (Optional) Flags, comma-separated. The following flags are available:
|
||||||
|
// - "emojis=<property>": include the specified emoji properties (e.g.
|
||||||
|
// "Extended_Pictographic").
|
||||||
|
// - "gencat": include general category properties.
|
||||||
|
//
|
||||||
|
//go:generate go run gen_properties.go auxiliary/GraphemeBreakProperty graphemeproperties.go graphemeCodePoints graphemes emojis=Extended_Pictographic
|
||||||
|
//go:generate go run gen_properties.go auxiliary/WordBreakProperty wordproperties.go workBreakCodePoints words emojis=Extended_Pictographic
|
||||||
|
//go:generate go run gen_properties.go auxiliary/SentenceBreakProperty sentenceproperties.go sentenceBreakCodePoints sentences
|
||||||
|
//go:generate go run gen_properties.go LineBreak lineproperties.go lineBreakCodePoints lines gencat
|
||||||
|
//go:generate go run gen_properties.go EastAsianWidth eastasianwidth.go eastAsianWidth eastasianwidth
|
||||||
|
//go:generate go run gen_properties.go - emojipresentation.go emojiPresentation emojipresentation emojis=Emoji_Presentation
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"go/format"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// We want to test against a specific version rather than the latest. When the
|
||||||
|
// package is upgraded to a new version, change these to generate new tests.
|
||||||
|
const (
|
||||||
|
propertyURL = `https://www.unicode.org/Public/15.0.0/ucd/%s.txt`
|
||||||
|
emojiURL = `https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt`
|
||||||
|
)
|
||||||
|
|
||||||
|
// The regular expression for a line containing a code point range property.
|
||||||
|
var propertyPattern = regexp.MustCompile(`^([0-9A-F]{4,6})(\.\.([0-9A-F]{4,6}))?\s*;\s*([A-Za-z0-9_]+)\s*#\s(.+)$`)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 5 {
|
||||||
|
fmt.Println("Not enough arguments, see code for details")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.SetPrefix("gen_properties (" + os.Args[4] + "): ")
|
||||||
|
log.SetFlags(0)
|
||||||
|
|
||||||
|
// Parse flags.
|
||||||
|
flags := make(map[string]string)
|
||||||
|
if len(os.Args) >= 6 {
|
||||||
|
for _, flag := range strings.Split(os.Args[5], ",") {
|
||||||
|
flagFields := strings.Split(flag, "=")
|
||||||
|
if len(flagFields) == 1 {
|
||||||
|
flags[flagFields[0]] = "yes"
|
||||||
|
} else {
|
||||||
|
flags[flagFields[0]] = flagFields[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the text file and generate Go source code from it.
|
||||||
|
_, includeGeneralCategory := flags["gencat"]
|
||||||
|
var mainURL string
|
||||||
|
if os.Args[1] != "-" {
|
||||||
|
mainURL = fmt.Sprintf(propertyURL, os.Args[1])
|
||||||
|
}
|
||||||
|
src, err := parse(mainURL, flags["emojis"], includeGeneralCategory)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the Go code.
|
||||||
|
formatted, err := format.Source([]byte(src))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("gofmt:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save it to the (local) target file.
|
||||||
|
log.Print("Writing to ", os.Args[2])
|
||||||
|
if err := ioutil.WriteFile(os.Args[2], formatted, 0644); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse parses the Unicode Properties text files located at the given URLs and
|
||||||
|
// returns their equivalent Go source code to be used in the uniseg package. If
|
||||||
|
// "emojiProperty" is not an empty string, emoji code points for that emoji
|
||||||
|
// property (e.g. "Extended_Pictographic") will be included. In those cases, you
|
||||||
|
// may pass an empty "propertyURL" to skip parsing the main properties file. If
|
||||||
|
// "includeGeneralCategory" is true, the Unicode General Category property will
|
||||||
|
// be extracted from the comments and included in the output.
|
||||||
|
func parse(propertyURL, emojiProperty string, includeGeneralCategory bool) (string, error) {
|
||||||
|
if propertyURL == "" && emojiProperty == "" {
|
||||||
|
return "", errors.New("no properties to parse")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temporary buffer to hold properties.
|
||||||
|
var properties [][4]string
|
||||||
|
|
||||||
|
// Open the first URL.
|
||||||
|
if propertyURL != "" {
|
||||||
|
log.Printf("Parsing %s", propertyURL)
|
||||||
|
res, err := http.Get(propertyURL)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
in1 := res.Body
|
||||||
|
defer in1.Close()
|
||||||
|
|
||||||
|
// Parse it.
|
||||||
|
scanner := bufio.NewScanner(in1)
|
||||||
|
num := 0
|
||||||
|
for scanner.Scan() {
|
||||||
|
num++
|
||||||
|
line := strings.TrimSpace(scanner.Text())
|
||||||
|
|
||||||
|
// Skip comments and empty lines.
|
||||||
|
if strings.HasPrefix(line, "#") || line == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything else must be a code point range, a property and a comment.
|
||||||
|
from, to, property, comment, err := parseProperty(line)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("%s line %d: %v", os.Args[4], num, err)
|
||||||
|
}
|
||||||
|
properties = append(properties, [4]string{from, to, property, comment})
|
||||||
|
}
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the second URL.
|
||||||
|
if emojiProperty != "" {
|
||||||
|
log.Printf("Parsing %s", emojiURL)
|
||||||
|
res, err := http.Get(emojiURL)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
in2 := res.Body
|
||||||
|
defer in2.Close()
|
||||||
|
|
||||||
|
// Parse it.
|
||||||
|
scanner := bufio.NewScanner(in2)
|
||||||
|
num := 0
|
||||||
|
for scanner.Scan() {
|
||||||
|
num++
|
||||||
|
line := scanner.Text()
|
||||||
|
|
||||||
|
// Skip comments, empty lines, and everything not containing
|
||||||
|
// "Extended_Pictographic".
|
||||||
|
if strings.HasPrefix(line, "#") || line == "" || !strings.Contains(line, emojiProperty) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything else must be a code point range, a property and a comment.
|
||||||
|
from, to, property, comment, err := parseProperty(line)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("emojis line %d: %v", num, err)
|
||||||
|
}
|
||||||
|
properties = append(properties, [4]string{from, to, property, comment})
|
||||||
|
}
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid overflow during binary search.
|
||||||
|
if len(properties) >= 1<<31 {
|
||||||
|
return "", errors.New("too many properties")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort properties.
|
||||||
|
sort.Slice(properties, func(i, j int) bool {
|
||||||
|
left, _ := strconv.ParseUint(properties[i][0], 16, 64)
|
||||||
|
right, _ := strconv.ParseUint(properties[j][0], 16, 64)
|
||||||
|
return left < right
|
||||||
|
})
|
||||||
|
|
||||||
|
// Header.
|
||||||
|
var (
|
||||||
|
buf bytes.Buffer
|
||||||
|
emojiComment string
|
||||||
|
)
|
||||||
|
columns := 3
|
||||||
|
if includeGeneralCategory {
|
||||||
|
columns = 4
|
||||||
|
}
|
||||||
|
if emojiURL != "" {
|
||||||
|
emojiComment = `
|
||||||
|
// and
|
||||||
|
// ` + emojiURL + `
|
||||||
|
// ("Extended_Pictographic" only)`
|
||||||
|
}
|
||||||
|
buf.WriteString(`// Code generated via go generate from gen_properties.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
// ` + os.Args[3] + ` are taken from
|
||||||
|
// ` + propertyURL + emojiComment + `
|
||||||
|
// on ` + time.Now().Format("January 2, 2006") + `. See https://www.unicode.org/license.html for the Unicode
|
||||||
|
// license agreement.
|
||||||
|
var ` + os.Args[3] + ` = [][` + strconv.Itoa(columns) + `]int{
|
||||||
|
`)
|
||||||
|
|
||||||
|
// Properties.
|
||||||
|
for _, prop := range properties {
|
||||||
|
if includeGeneralCategory {
|
||||||
|
generalCategory := "gc" + prop[3][:2]
|
||||||
|
if generalCategory == "gcL&" {
|
||||||
|
generalCategory = "gcLC"
|
||||||
|
}
|
||||||
|
prop[3] = prop[3][3:]
|
||||||
|
fmt.Fprintf(&buf, "{0x%s,0x%s,%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), generalCategory, prop[3])
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(&buf, "{0x%s,0x%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), prop[3])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tail.
|
||||||
|
buf.WriteString("}")
|
||||||
|
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseProperty parses a line of the Unicode properties text file containing a
|
||||||
|
// property for a code point range and returns it along with its comment.
|
||||||
|
func parseProperty(line string) (from, to, property, comment string, err error) {
|
||||||
|
fields := propertyPattern.FindStringSubmatch(line)
|
||||||
|
if fields == nil {
|
||||||
|
err = errors.New("no property found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
from = fields[1]
|
||||||
|
to = fields[3]
|
||||||
|
if to == "" {
|
||||||
|
to = from
|
||||||
|
}
|
||||||
|
property = fields[4]
|
||||||
|
comment = fields[5]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// translateProperty translates a property name as used in the Unicode data file
|
||||||
|
// to a variable used in the Go code.
|
||||||
|
func translateProperty(prefix, property string) string {
|
||||||
|
return prefix + strings.ReplaceAll(property, "_", "")
|
||||||
|
}
|
|
@ -0,0 +1,331 @@
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
// Graphemes implements an iterator over Unicode grapheme clusters, or
|
||||||
|
// user-perceived characters. While iterating, it also provides information
|
||||||
|
// about word boundaries, sentence boundaries, line breaks, and monospace
|
||||||
|
// character widths.
|
||||||
|
//
|
||||||
|
// After constructing the class via [NewGraphemes] for a given string "str",
|
||||||
|
// [Graphemes.Next] is called for every grapheme cluster in a loop until it
|
||||||
|
// returns false. Inside the loop, information about the grapheme cluster as
|
||||||
|
// well as boundary information and character width is available via the various
|
||||||
|
// methods (see examples below).
|
||||||
|
//
|
||||||
|
// This class basically wraps the [StepString] parser and provides a convenient
|
||||||
|
// interface to it. If you are only interested in some parts of this package's
|
||||||
|
// functionality, using the specialized functions starting with "First" is
|
||||||
|
// almost always faster.
|
||||||
|
type Graphemes struct {
|
||||||
|
// The original string.
|
||||||
|
original string
|
||||||
|
|
||||||
|
// The remaining string to be parsed.
|
||||||
|
remaining string
|
||||||
|
|
||||||
|
// The current grapheme cluster.
|
||||||
|
cluster string
|
||||||
|
|
||||||
|
// The byte offset of the current grapheme cluster relative to the original
|
||||||
|
// string.
|
||||||
|
offset int
|
||||||
|
|
||||||
|
// The current boundary information of the [Step] parser.
|
||||||
|
boundaries int
|
||||||
|
|
||||||
|
// The current state of the [Step] parser.
|
||||||
|
state int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGraphemes returns a new grapheme cluster iterator.
|
||||||
|
func NewGraphemes(str string) *Graphemes {
|
||||||
|
return &Graphemes{
|
||||||
|
original: str,
|
||||||
|
remaining: str,
|
||||||
|
state: -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next advances the iterator by one grapheme cluster and returns false if no
|
||||||
|
// clusters are left. This function must be called before the first cluster is
|
||||||
|
// accessed.
|
||||||
|
func (g *Graphemes) Next() bool {
|
||||||
|
if len(g.remaining) == 0 {
|
||||||
|
// We're already past the end.
|
||||||
|
g.state = -2
|
||||||
|
g.cluster = ""
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
g.offset += len(g.cluster)
|
||||||
|
g.cluster, g.remaining, g.boundaries, g.state = StepString(g.remaining, g.state)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runes returns a slice of runes (code points) which corresponds to the current
|
||||||
|
// grapheme cluster. If the iterator is already past the end or [Graphemes.Next]
|
||||||
|
// has not yet been called, nil is returned.
|
||||||
|
func (g *Graphemes) Runes() []rune {
|
||||||
|
if g.state < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return []rune(g.cluster)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Str returns a substring of the original string which corresponds to the
|
||||||
|
// current grapheme cluster. If the iterator is already past the end or
|
||||||
|
// [Graphemes.Next] has not yet been called, an empty string is returned.
|
||||||
|
func (g *Graphemes) Str() string {
|
||||||
|
return g.cluster
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns a byte slice which corresponds to the current grapheme cluster.
|
||||||
|
// If the iterator is already past the end or [Graphemes.Next] has not yet been
|
||||||
|
// called, nil is returned.
|
||||||
|
func (g *Graphemes) Bytes() []byte {
|
||||||
|
if g.state < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return []byte(g.cluster)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Positions returns the interval of the current grapheme cluster as byte
|
||||||
|
// positions into the original string. The first returned value "from" indexes
|
||||||
|
// the first byte and the second returned value "to" indexes the first byte that
|
||||||
|
// is not included anymore, i.e. str[from:to] is the current grapheme cluster of
|
||||||
|
// the original string "str". If [Graphemes.Next] has not yet been called, both
|
||||||
|
// values are 0. If the iterator is already past the end, both values are 1.
|
||||||
|
func (g *Graphemes) Positions() (int, int) {
|
||||||
|
if g.state == -1 {
|
||||||
|
return 0, 0
|
||||||
|
} else if g.state == -2 {
|
||||||
|
return 1, 1
|
||||||
|
}
|
||||||
|
return g.offset, g.offset + len(g.cluster)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsWordBoundary returns true if a word ends after the current grapheme
|
||||||
|
// cluster.
|
||||||
|
func (g *Graphemes) IsWordBoundary() bool {
|
||||||
|
if g.state < 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return g.boundaries&MaskWord != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSentenceBoundary returns true if a sentence ends after the current
|
||||||
|
// grapheme cluster.
|
||||||
|
func (g *Graphemes) IsSentenceBoundary() bool {
|
||||||
|
if g.state < 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return g.boundaries&MaskSentence != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// LineBreak returns whether the line can be broken after the current grapheme
|
||||||
|
// cluster. A value of [LineDontBreak] means the line may not be broken, a value
|
||||||
|
// of [LineMustBreak] means the line must be broken, and a value of
|
||||||
|
// [LineCanBreak] means the line may or may not be broken.
|
||||||
|
func (g *Graphemes) LineBreak() int {
|
||||||
|
if g.state == -1 {
|
||||||
|
return LineDontBreak
|
||||||
|
}
|
||||||
|
if g.state == -2 {
|
||||||
|
return LineMustBreak
|
||||||
|
}
|
||||||
|
return g.boundaries & MaskLine
|
||||||
|
}
|
||||||
|
|
||||||
|
// Width returns the monospace width of the current grapheme cluster.
|
||||||
|
func (g *Graphemes) Width() int {
|
||||||
|
if g.state < 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return g.boundaries >> ShiftWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset puts the iterator into its initial state such that the next call to
|
||||||
|
// [Graphemes.Next] sets it to the first grapheme cluster again.
|
||||||
|
func (g *Graphemes) Reset() {
|
||||||
|
g.state = -1
|
||||||
|
g.offset = 0
|
||||||
|
g.cluster = ""
|
||||||
|
g.remaining = g.original
|
||||||
|
}
|
||||||
|
|
||||||
|
// GraphemeClusterCount returns the number of user-perceived characters
|
||||||
|
// (grapheme clusters) for the given string.
|
||||||
|
func GraphemeClusterCount(s string) (n int) {
|
||||||
|
state := -1
|
||||||
|
for len(s) > 0 {
|
||||||
|
_, s, _, state = FirstGraphemeClusterInString(s, state)
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReverseString reverses the given string while observing grapheme cluster
|
||||||
|
// boundaries.
|
||||||
|
func ReverseString(s string) string {
|
||||||
|
str := []byte(s)
|
||||||
|
reversed := make([]byte, len(str))
|
||||||
|
state := -1
|
||||||
|
index := len(str)
|
||||||
|
for len(str) > 0 {
|
||||||
|
var cluster []byte
|
||||||
|
cluster, str, _, state = FirstGraphemeCluster(str, state)
|
||||||
|
index -= len(cluster)
|
||||||
|
copy(reversed[index:], cluster)
|
||||||
|
if index <= len(str)/2 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(reversed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The number of bits the grapheme property must be shifted to make place for
|
||||||
|
// grapheme states.
|
||||||
|
const shiftGraphemePropState = 4
|
||||||
|
|
||||||
|
// FirstGraphemeCluster returns the first grapheme cluster found in the given
|
||||||
|
// byte slice according to the rules of [Unicode Standard Annex #29, Grapheme
|
||||||
|
// Cluster Boundaries]. This function can be called continuously to extract all
|
||||||
|
// grapheme clusters from a byte slice, as illustrated in the example below.
|
||||||
|
//
|
||||||
|
// If you don't know the current state, for example when calling the function
|
||||||
|
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||||
|
// and rest slice returned by the previous call.
|
||||||
|
//
|
||||||
|
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||||
|
// after the last byte of the identified grapheme cluster. If the length of the
|
||||||
|
// "rest" slice is 0, the entire byte slice "b" has been processed. The
|
||||||
|
// "cluster" byte slice is the sub-slice of the input slice containing the
|
||||||
|
// identified grapheme cluster.
|
||||||
|
//
|
||||||
|
// The returned width is the width of the grapheme cluster for most monospace
|
||||||
|
// fonts where a value of 1 represents one character cell.
|
||||||
|
//
|
||||||
|
// Given an empty byte slice "b", the function returns nil values.
|
||||||
|
//
|
||||||
|
// While slightly less convenient than using the Graphemes class, this function
|
||||||
|
// has much better performance and makes no allocations. It lends itself well to
|
||||||
|
// large byte slices.
|
||||||
|
//
|
||||||
|
// [Unicode Standard Annex #29, Grapheme Cluster Boundaries]: http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
|
||||||
|
func FirstGraphemeCluster(b []byte, state int) (cluster, rest []byte, width, newState int) {
|
||||||
|
// An empty byte slice returns nothing.
|
||||||
|
if len(b) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the first rune.
|
||||||
|
r, length := utf8.DecodeRune(b)
|
||||||
|
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||||
|
var prop int
|
||||||
|
if state < 0 {
|
||||||
|
prop = propertyGraphemes(r)
|
||||||
|
} else {
|
||||||
|
prop = state >> shiftGraphemePropState
|
||||||
|
}
|
||||||
|
return b, nil, runeWidth(r, prop), grAny | (prop << shiftGraphemePropState)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't know the state, determine it now.
|
||||||
|
var firstProp int
|
||||||
|
if state < 0 {
|
||||||
|
state, firstProp, _ = transitionGraphemeState(state, r)
|
||||||
|
} else {
|
||||||
|
firstProp = state >> shiftGraphemePropState
|
||||||
|
}
|
||||||
|
width += runeWidth(r, firstProp)
|
||||||
|
|
||||||
|
// Transition until we find a boundary.
|
||||||
|
for {
|
||||||
|
var (
|
||||||
|
prop int
|
||||||
|
boundary bool
|
||||||
|
)
|
||||||
|
|
||||||
|
r, l := utf8.DecodeRune(b[length:])
|
||||||
|
state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r)
|
||||||
|
|
||||||
|
if boundary {
|
||||||
|
return b[:length], b[length:], width, state | (prop << shiftGraphemePropState)
|
||||||
|
}
|
||||||
|
|
||||||
|
if firstProp == prExtendedPictographic {
|
||||||
|
if r == vs15 {
|
||||||
|
width = 1
|
||||||
|
} else if r == vs16 {
|
||||||
|
width = 2
|
||||||
|
}
|
||||||
|
} else if firstProp != prRegionalIndicator && firstProp != prL {
|
||||||
|
width += runeWidth(r, prop)
|
||||||
|
}
|
||||||
|
|
||||||
|
length += l
|
||||||
|
if len(b) <= length {
|
||||||
|
return b, nil, width, grAny | (prop << shiftGraphemePropState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstGraphemeClusterInString is like [FirstGraphemeCluster] but its input and
|
||||||
|
// outputs are strings.
|
||||||
|
func FirstGraphemeClusterInString(str string, state int) (cluster, rest string, width, newState int) {
|
||||||
|
// An empty string returns nothing.
|
||||||
|
if len(str) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the first rune.
|
||||||
|
r, length := utf8.DecodeRuneInString(str)
|
||||||
|
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||||
|
var prop int
|
||||||
|
if state < 0 {
|
||||||
|
prop = propertyGraphemes(r)
|
||||||
|
} else {
|
||||||
|
prop = state >> shiftGraphemePropState
|
||||||
|
}
|
||||||
|
return str, "", runeWidth(r, prop), grAny | (prop << shiftGraphemePropState)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't know the state, determine it now.
|
||||||
|
var firstProp int
|
||||||
|
if state < 0 {
|
||||||
|
state, firstProp, _ = transitionGraphemeState(state, r)
|
||||||
|
} else {
|
||||||
|
firstProp = state >> shiftGraphemePropState
|
||||||
|
}
|
||||||
|
width += runeWidth(r, firstProp)
|
||||||
|
|
||||||
|
// Transition until we find a boundary.
|
||||||
|
for {
|
||||||
|
var (
|
||||||
|
prop int
|
||||||
|
boundary bool
|
||||||
|
)
|
||||||
|
|
||||||
|
r, l := utf8.DecodeRuneInString(str[length:])
|
||||||
|
state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r)
|
||||||
|
|
||||||
|
if boundary {
|
||||||
|
return str[:length], str[length:], width, state | (prop << shiftGraphemePropState)
|
||||||
|
}
|
||||||
|
|
||||||
|
if firstProp == prExtendedPictographic {
|
||||||
|
if r == vs15 {
|
||||||
|
width = 1
|
||||||
|
} else if r == vs16 {
|
||||||
|
width = 2
|
||||||
|
}
|
||||||
|
} else if firstProp != prRegionalIndicator && firstProp != prL {
|
||||||
|
width += runeWidth(r, prop)
|
||||||
|
}
|
||||||
|
|
||||||
|
length += l
|
||||||
|
if len(str) <= length {
|
||||||
|
return str, "", width, grAny | (prop << shiftGraphemePropState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1915
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/graphemeproperties.go
generated
vendored
Normal file
1915
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/graphemeproperties.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,176 @@
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
// The states of the grapheme cluster parser.
|
||||||
|
const (
|
||||||
|
grAny = iota
|
||||||
|
grCR
|
||||||
|
grControlLF
|
||||||
|
grL
|
||||||
|
grLVV
|
||||||
|
grLVTT
|
||||||
|
grPrepend
|
||||||
|
grExtendedPictographic
|
||||||
|
grExtendedPictographicZWJ
|
||||||
|
grRIOdd
|
||||||
|
grRIEven
|
||||||
|
)
|
||||||
|
|
||||||
|
// The grapheme cluster parser's breaking instructions.
|
||||||
|
const (
|
||||||
|
grNoBoundary = iota
|
||||||
|
grBoundary
|
||||||
|
)
|
||||||
|
|
||||||
|
// grTransitions implements the grapheme cluster parser's state transitions.
|
||||||
|
// Maps state and property to a new state, a breaking instruction, and rule
|
||||||
|
// number. The breaking instruction always refers to the boundary between the
|
||||||
|
// last and next code point. Returns negative values if no transition is found.
|
||||||
|
//
|
||||||
|
// This function is used as follows:
|
||||||
|
//
|
||||||
|
// 1. Find specific state + specific property. Stop if found.
|
||||||
|
// 2. Find specific state + any property.
|
||||||
|
// 3. Find any state + specific property.
|
||||||
|
// 4. If only (2) or (3) (but not both) was found, stop.
|
||||||
|
// 5. If both (2) and (3) were found, use state from (3) and breaking instruction
|
||||||
|
// from the transition with the lower rule number, prefer (3) if rule numbers
|
||||||
|
// are equal. Stop.
|
||||||
|
// 6. Assume grAny and grBoundary.
|
||||||
|
//
|
||||||
|
// Unicode version 15.0.0.
|
||||||
|
func grTransitions(state, prop int) (newState int, newProp int, boundary int) {
|
||||||
|
// It turns out that using a big switch statement is much faster than using
|
||||||
|
// a map.
|
||||||
|
|
||||||
|
switch uint64(state) | uint64(prop)<<32 {
|
||||||
|
// GB5
|
||||||
|
case grAny | prCR<<32:
|
||||||
|
return grCR, grBoundary, 50
|
||||||
|
case grAny | prLF<<32:
|
||||||
|
return grControlLF, grBoundary, 50
|
||||||
|
case grAny | prControl<<32:
|
||||||
|
return grControlLF, grBoundary, 50
|
||||||
|
|
||||||
|
// GB4
|
||||||
|
case grCR | prAny<<32:
|
||||||
|
return grAny, grBoundary, 40
|
||||||
|
case grControlLF | prAny<<32:
|
||||||
|
return grAny, grBoundary, 40
|
||||||
|
|
||||||
|
// GB3
|
||||||
|
case grCR | prLF<<32:
|
||||||
|
return grControlLF, grNoBoundary, 30
|
||||||
|
|
||||||
|
// GB6
|
||||||
|
case grAny | prL<<32:
|
||||||
|
return grL, grBoundary, 9990
|
||||||
|
case grL | prL<<32:
|
||||||
|
return grL, grNoBoundary, 60
|
||||||
|
case grL | prV<<32:
|
||||||
|
return grLVV, grNoBoundary, 60
|
||||||
|
case grL | prLV<<32:
|
||||||
|
return grLVV, grNoBoundary, 60
|
||||||
|
case grL | prLVT<<32:
|
||||||
|
return grLVTT, grNoBoundary, 60
|
||||||
|
|
||||||
|
// GB7
|
||||||
|
case grAny | prLV<<32:
|
||||||
|
return grLVV, grBoundary, 9990
|
||||||
|
case grAny | prV<<32:
|
||||||
|
return grLVV, grBoundary, 9990
|
||||||
|
case grLVV | prV<<32:
|
||||||
|
return grLVV, grNoBoundary, 70
|
||||||
|
case grLVV | prT<<32:
|
||||||
|
return grLVTT, grNoBoundary, 70
|
||||||
|
|
||||||
|
// GB8
|
||||||
|
case grAny | prLVT<<32:
|
||||||
|
return grLVTT, grBoundary, 9990
|
||||||
|
case grAny | prT<<32:
|
||||||
|
return grLVTT, grBoundary, 9990
|
||||||
|
case grLVTT | prT<<32:
|
||||||
|
return grLVTT, grNoBoundary, 80
|
||||||
|
|
||||||
|
// GB9
|
||||||
|
case grAny | prExtend<<32:
|
||||||
|
return grAny, grNoBoundary, 90
|
||||||
|
case grAny | prZWJ<<32:
|
||||||
|
return grAny, grNoBoundary, 90
|
||||||
|
|
||||||
|
// GB9a
|
||||||
|
case grAny | prSpacingMark<<32:
|
||||||
|
return grAny, grNoBoundary, 91
|
||||||
|
|
||||||
|
// GB9b
|
||||||
|
case grAny | prPrepend<<32:
|
||||||
|
return grPrepend, grBoundary, 9990
|
||||||
|
case grPrepend | prAny<<32:
|
||||||
|
return grAny, grNoBoundary, 92
|
||||||
|
|
||||||
|
// GB11
|
||||||
|
case grAny | prExtendedPictographic<<32:
|
||||||
|
return grExtendedPictographic, grBoundary, 9990
|
||||||
|
case grExtendedPictographic | prExtend<<32:
|
||||||
|
return grExtendedPictographic, grNoBoundary, 110
|
||||||
|
case grExtendedPictographic | prZWJ<<32:
|
||||||
|
return grExtendedPictographicZWJ, grNoBoundary, 110
|
||||||
|
case grExtendedPictographicZWJ | prExtendedPictographic<<32:
|
||||||
|
return grExtendedPictographic, grNoBoundary, 110
|
||||||
|
|
||||||
|
// GB12 / GB13
|
||||||
|
case grAny | prRegionalIndicator<<32:
|
||||||
|
return grRIOdd, grBoundary, 9990
|
||||||
|
case grRIOdd | prRegionalIndicator<<32:
|
||||||
|
return grRIEven, grNoBoundary, 120
|
||||||
|
case grRIEven | prRegionalIndicator<<32:
|
||||||
|
return grRIOdd, grBoundary, 120
|
||||||
|
default:
|
||||||
|
return -1, -1, -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// transitionGraphemeState determines the new state of the grapheme cluster
|
||||||
|
// parser given the current state and the next code point. It also returns the
|
||||||
|
// code point's grapheme property (the value mapped by the [graphemeCodePoints]
|
||||||
|
// table) and whether a cluster boundary was detected.
|
||||||
|
func transitionGraphemeState(state int, r rune) (newState, prop int, boundary bool) {
|
||||||
|
// Determine the property of the next character.
|
||||||
|
prop = propertyGraphemes(r)
|
||||||
|
|
||||||
|
// Find the applicable transition.
|
||||||
|
nextState, nextProp, _ := grTransitions(state, prop)
|
||||||
|
if nextState >= 0 {
|
||||||
|
// We have a specific transition. We'll use it.
|
||||||
|
return nextState, prop, nextProp == grBoundary
|
||||||
|
}
|
||||||
|
|
||||||
|
// No specific transition found. Try the less specific ones.
|
||||||
|
anyPropState, anyPropProp, anyPropRule := grTransitions(state, prAny)
|
||||||
|
anyStateState, anyStateProp, anyStateRule := grTransitions(grAny, prop)
|
||||||
|
if anyPropState >= 0 && anyStateState >= 0 {
|
||||||
|
// Both apply. We'll use a mix (see comments for grTransitions).
|
||||||
|
newState = anyStateState
|
||||||
|
boundary = anyStateProp == grBoundary
|
||||||
|
if anyPropRule < anyStateRule {
|
||||||
|
boundary = anyPropProp == grBoundary
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if anyPropState >= 0 {
|
||||||
|
// We only have a specific state.
|
||||||
|
return anyPropState, prop, anyPropProp == grBoundary
|
||||||
|
// This branch will probably never be reached because okAnyState will
|
||||||
|
// always be true given the current transition map. But we keep it here
|
||||||
|
// for future modifications to the transition map where this may not be
|
||||||
|
// true anymore.
|
||||||
|
}
|
||||||
|
|
||||||
|
if anyStateState >= 0 {
|
||||||
|
// We only have a specific property.
|
||||||
|
return anyStateState, prop, anyStateProp == grBoundary
|
||||||
|
}
|
||||||
|
|
||||||
|
// No known transition. GB999: Any ÷ Any.
|
||||||
|
return grAny, prop, true
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
// FirstLineSegment returns the prefix of the given byte slice after which a
|
||||||
|
// decision to break the string over to the next line can or must be made,
|
||||||
|
// according to the rules of [Unicode Standard Annex #14]. This is used to
|
||||||
|
// implement line breaking.
|
||||||
|
//
|
||||||
|
// Line breaking, also known as word wrapping, is the process of breaking a
|
||||||
|
// section of text into lines such that it will fit in the available width of a
|
||||||
|
// page, window or other display area.
|
||||||
|
//
|
||||||
|
// The returned "segment" may not be broken into smaller parts, unless no other
|
||||||
|
// breaking opportunities present themselves, in which case you may break by
|
||||||
|
// grapheme clusters (using the [FirstGraphemeCluster] function to determine the
|
||||||
|
// grapheme clusters).
|
||||||
|
//
|
||||||
|
// The "mustBreak" flag indicates whether you MUST break the line after the
|
||||||
|
// given segment (true), for example after newline characters, or you MAY break
|
||||||
|
// the line after the given segment (false).
|
||||||
|
//
|
||||||
|
// This function can be called continuously to extract all non-breaking sub-sets
|
||||||
|
// from a byte slice, as illustrated in the example below.
|
||||||
|
//
|
||||||
|
// If you don't know the current state, for example when calling the function
|
||||||
|
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||||
|
// and rest slice returned by the previous call.
|
||||||
|
//
|
||||||
|
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||||
|
// after the last byte of the identified line segment. If the length of the
|
||||||
|
// "rest" slice is 0, the entire byte slice "b" has been processed. The
|
||||||
|
// "segment" byte slice is the sub-slice of the input slice containing the
|
||||||
|
// identified line segment.
|
||||||
|
//
|
||||||
|
// Given an empty byte slice "b", the function returns nil values.
|
||||||
|
//
|
||||||
|
// Note that in accordance with [UAX #14 LB3], the final segment will end with
|
||||||
|
// "mustBreak" set to true. You can choose to ignore this by checking if the
|
||||||
|
// length of the "rest" slice is 0 and calling [HasTrailingLineBreak] or
|
||||||
|
// [HasTrailingLineBreakInString] on the last rune.
|
||||||
|
//
|
||||||
|
// Note also that this algorithm may break within grapheme clusters. This is
|
||||||
|
// addressed in Section 8.2 Example 6 of UAX #14. To avoid this, you can use
|
||||||
|
// the [Step] function instead.
|
||||||
|
//
|
||||||
|
// [Unicode Standard Annex #14]: https://www.unicode.org/reports/tr14/
|
||||||
|
// [UAX #14 LB3]: https://www.unicode.org/reports/tr14/#Algorithm
|
||||||
|
func FirstLineSegment(b []byte, state int) (segment, rest []byte, mustBreak bool, newState int) {
|
||||||
|
// An empty byte slice returns nothing.
|
||||||
|
if len(b) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the first rune.
|
||||||
|
r, length := utf8.DecodeRune(b)
|
||||||
|
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||||
|
return b, nil, true, lbAny // LB3.
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't know the state, determine it now.
|
||||||
|
if state < 0 {
|
||||||
|
state, _ = transitionLineBreakState(state, r, b[length:], "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition until we find a boundary.
|
||||||
|
var boundary int
|
||||||
|
for {
|
||||||
|
r, l := utf8.DecodeRune(b[length:])
|
||||||
|
state, boundary = transitionLineBreakState(state, r, b[length+l:], "")
|
||||||
|
|
||||||
|
if boundary != LineDontBreak {
|
||||||
|
return b[:length], b[length:], boundary == LineMustBreak, state
|
||||||
|
}
|
||||||
|
|
||||||
|
length += l
|
||||||
|
if len(b) <= length {
|
||||||
|
return b, nil, true, lbAny // LB3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstLineSegmentInString is like [FirstLineSegment] but its input and outputs
|
||||||
|
// are strings.
|
||||||
|
func FirstLineSegmentInString(str string, state int) (segment, rest string, mustBreak bool, newState int) {
|
||||||
|
// An empty byte slice returns nothing.
|
||||||
|
if len(str) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the first rune.
|
||||||
|
r, length := utf8.DecodeRuneInString(str)
|
||||||
|
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||||
|
return str, "", true, lbAny // LB3.
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't know the state, determine it now.
|
||||||
|
if state < 0 {
|
||||||
|
state, _ = transitionLineBreakState(state, r, nil, str[length:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition until we find a boundary.
|
||||||
|
var boundary int
|
||||||
|
for {
|
||||||
|
r, l := utf8.DecodeRuneInString(str[length:])
|
||||||
|
state, boundary = transitionLineBreakState(state, r, nil, str[length+l:])
|
||||||
|
|
||||||
|
if boundary != LineDontBreak {
|
||||||
|
return str[:length], str[length:], boundary == LineMustBreak, state
|
||||||
|
}
|
||||||
|
|
||||||
|
length += l
|
||||||
|
if len(str) <= length {
|
||||||
|
return str, "", true, lbAny // LB3.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasTrailingLineBreak returns true if the last rune in the given byte slice is
|
||||||
|
// one of the hard line break code points defined in LB4 and LB5 of [UAX #14].
|
||||||
|
//
|
||||||
|
// [UAX #14]: https://www.unicode.org/reports/tr14/#Algorithm
|
||||||
|
func HasTrailingLineBreak(b []byte) bool {
|
||||||
|
r, _ := utf8.DecodeLastRune(b)
|
||||||
|
property, _ := propertyLineBreak(r)
|
||||||
|
return property == prBK || property == prCR || property == prLF || property == prNL
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasTrailingLineBreakInString is like [HasTrailingLineBreak] but for a string.
|
||||||
|
func HasTrailingLineBreakInString(str string) bool {
|
||||||
|
r, _ := utf8.DecodeLastRuneInString(str)
|
||||||
|
property, _ := propertyLineBreak(r)
|
||||||
|
return property == prBK || property == prCR || property == prLF || property == prNL
|
||||||
|
}
|
3554
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/lineproperties.go
generated
vendored
Normal file
3554
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/lineproperties.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,626 @@
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
// The states of the line break parser.
|
||||||
|
const (
|
||||||
|
lbAny = iota
|
||||||
|
lbBK
|
||||||
|
lbCR
|
||||||
|
lbLF
|
||||||
|
lbNL
|
||||||
|
lbSP
|
||||||
|
lbZW
|
||||||
|
lbWJ
|
||||||
|
lbGL
|
||||||
|
lbBA
|
||||||
|
lbHY
|
||||||
|
lbCL
|
||||||
|
lbCP
|
||||||
|
lbEX
|
||||||
|
lbIS
|
||||||
|
lbSY
|
||||||
|
lbOP
|
||||||
|
lbQU
|
||||||
|
lbQUSP
|
||||||
|
lbNS
|
||||||
|
lbCLCPSP
|
||||||
|
lbB2
|
||||||
|
lbB2SP
|
||||||
|
lbCB
|
||||||
|
lbBB
|
||||||
|
lbLB21a
|
||||||
|
lbHL
|
||||||
|
lbAL
|
||||||
|
lbNU
|
||||||
|
lbPR
|
||||||
|
lbEB
|
||||||
|
lbIDEM
|
||||||
|
lbNUNU
|
||||||
|
lbNUSY
|
||||||
|
lbNUIS
|
||||||
|
lbNUCL
|
||||||
|
lbNUCP
|
||||||
|
lbPO
|
||||||
|
lbJL
|
||||||
|
lbJV
|
||||||
|
lbJT
|
||||||
|
lbH2
|
||||||
|
lbH3
|
||||||
|
lbOddRI
|
||||||
|
lbEvenRI
|
||||||
|
lbExtPicCn
|
||||||
|
lbZWJBit = 64
|
||||||
|
lbCPeaFWHBit = 128
|
||||||
|
)
|
||||||
|
|
||||||
|
// These constants define whether a given text may be broken into the next line.
|
||||||
|
// If the break is optional (LineCanBreak), you may choose to break or not based
|
||||||
|
// on your own criteria, for example, if the text has reached the available
|
||||||
|
// width.
|
||||||
|
const (
|
||||||
|
LineDontBreak = iota // You may not break the line here.
|
||||||
|
LineCanBreak // You may or may not break the line here.
|
||||||
|
LineMustBreak // You must break the line here.
|
||||||
|
)
|
||||||
|
|
||||||
|
// lbTransitions implements the line break parser's state transitions. It's
|
||||||
|
// anologous to [grTransitions], see comments there for details.
|
||||||
|
//
|
||||||
|
// Unicode version 15.0.0.
|
||||||
|
func lbTransitions(state, prop int) (newState, lineBreak, rule int) {
|
||||||
|
switch uint64(state) | uint64(prop)<<32 {
|
||||||
|
// LB4.
|
||||||
|
case lbBK | prAny<<32:
|
||||||
|
return lbAny, LineMustBreak, 40
|
||||||
|
|
||||||
|
// LB5.
|
||||||
|
case lbCR | prLF<<32:
|
||||||
|
return lbLF, LineDontBreak, 50
|
||||||
|
case lbCR | prAny<<32:
|
||||||
|
return lbAny, LineMustBreak, 50
|
||||||
|
case lbLF | prAny<<32:
|
||||||
|
return lbAny, LineMustBreak, 50
|
||||||
|
case lbNL | prAny<<32:
|
||||||
|
return lbAny, LineMustBreak, 50
|
||||||
|
|
||||||
|
// LB6.
|
||||||
|
case lbAny | prBK<<32:
|
||||||
|
return lbBK, LineDontBreak, 60
|
||||||
|
case lbAny | prCR<<32:
|
||||||
|
return lbCR, LineDontBreak, 60
|
||||||
|
case lbAny | prLF<<32:
|
||||||
|
return lbLF, LineDontBreak, 60
|
||||||
|
case lbAny | prNL<<32:
|
||||||
|
return lbNL, LineDontBreak, 60
|
||||||
|
|
||||||
|
// LB7.
|
||||||
|
case lbAny | prSP<<32:
|
||||||
|
return lbSP, LineDontBreak, 70
|
||||||
|
case lbAny | prZW<<32:
|
||||||
|
return lbZW, LineDontBreak, 70
|
||||||
|
|
||||||
|
// LB8.
|
||||||
|
case lbZW | prSP<<32:
|
||||||
|
return lbZW, LineDontBreak, 70
|
||||||
|
case lbZW | prAny<<32:
|
||||||
|
return lbAny, LineCanBreak, 80
|
||||||
|
|
||||||
|
// LB11.
|
||||||
|
case lbAny | prWJ<<32:
|
||||||
|
return lbWJ, LineDontBreak, 110
|
||||||
|
case lbWJ | prAny<<32:
|
||||||
|
return lbAny, LineDontBreak, 110
|
||||||
|
|
||||||
|
// LB12.
|
||||||
|
case lbAny | prGL<<32:
|
||||||
|
return lbGL, LineCanBreak, 310
|
||||||
|
case lbGL | prAny<<32:
|
||||||
|
return lbAny, LineDontBreak, 120
|
||||||
|
|
||||||
|
// LB13 (simple transitions).
|
||||||
|
case lbAny | prCL<<32:
|
||||||
|
return lbCL, LineCanBreak, 310
|
||||||
|
case lbAny | prCP<<32:
|
||||||
|
return lbCP, LineCanBreak, 310
|
||||||
|
case lbAny | prEX<<32:
|
||||||
|
return lbEX, LineDontBreak, 130
|
||||||
|
case lbAny | prIS<<32:
|
||||||
|
return lbIS, LineCanBreak, 310
|
||||||
|
case lbAny | prSY<<32:
|
||||||
|
return lbSY, LineCanBreak, 310
|
||||||
|
|
||||||
|
// LB14.
|
||||||
|
case lbAny | prOP<<32:
|
||||||
|
return lbOP, LineCanBreak, 310
|
||||||
|
case lbOP | prSP<<32:
|
||||||
|
return lbOP, LineDontBreak, 70
|
||||||
|
case lbOP | prAny<<32:
|
||||||
|
return lbAny, LineDontBreak, 140
|
||||||
|
|
||||||
|
// LB15.
|
||||||
|
case lbQU | prSP<<32:
|
||||||
|
return lbQUSP, LineDontBreak, 70
|
||||||
|
case lbQU | prOP<<32:
|
||||||
|
return lbOP, LineDontBreak, 150
|
||||||
|
case lbQUSP | prOP<<32:
|
||||||
|
return lbOP, LineDontBreak, 150
|
||||||
|
|
||||||
|
// LB16.
|
||||||
|
case lbCL | prSP<<32:
|
||||||
|
return lbCLCPSP, LineDontBreak, 70
|
||||||
|
case lbNUCL | prSP<<32:
|
||||||
|
return lbCLCPSP, LineDontBreak, 70
|
||||||
|
case lbCP | prSP<<32:
|
||||||
|
return lbCLCPSP, LineDontBreak, 70
|
||||||
|
case lbNUCP | prSP<<32:
|
||||||
|
return lbCLCPSP, LineDontBreak, 70
|
||||||
|
case lbCL | prNS<<32:
|
||||||
|
return lbNS, LineDontBreak, 160
|
||||||
|
case lbNUCL | prNS<<32:
|
||||||
|
return lbNS, LineDontBreak, 160
|
||||||
|
case lbCP | prNS<<32:
|
||||||
|
return lbNS, LineDontBreak, 160
|
||||||
|
case lbNUCP | prNS<<32:
|
||||||
|
return lbNS, LineDontBreak, 160
|
||||||
|
case lbCLCPSP | prNS<<32:
|
||||||
|
return lbNS, LineDontBreak, 160
|
||||||
|
|
||||||
|
// LB17.
|
||||||
|
case lbAny | prB2<<32:
|
||||||
|
return lbB2, LineCanBreak, 310
|
||||||
|
case lbB2 | prSP<<32:
|
||||||
|
return lbB2SP, LineDontBreak, 70
|
||||||
|
case lbB2 | prB2<<32:
|
||||||
|
return lbB2, LineDontBreak, 170
|
||||||
|
case lbB2SP | prB2<<32:
|
||||||
|
return lbB2, LineDontBreak, 170
|
||||||
|
|
||||||
|
// LB18.
|
||||||
|
case lbSP | prAny<<32:
|
||||||
|
return lbAny, LineCanBreak, 180
|
||||||
|
case lbQUSP | prAny<<32:
|
||||||
|
return lbAny, LineCanBreak, 180
|
||||||
|
case lbCLCPSP | prAny<<32:
|
||||||
|
return lbAny, LineCanBreak, 180
|
||||||
|
case lbB2SP | prAny<<32:
|
||||||
|
return lbAny, LineCanBreak, 180
|
||||||
|
|
||||||
|
// LB19.
|
||||||
|
case lbAny | prQU<<32:
|
||||||
|
return lbQU, LineDontBreak, 190
|
||||||
|
case lbQU | prAny<<32:
|
||||||
|
return lbAny, LineDontBreak, 190
|
||||||
|
|
||||||
|
// LB20.
|
||||||
|
case lbAny | prCB<<32:
|
||||||
|
return lbCB, LineCanBreak, 200
|
||||||
|
case lbCB | prAny<<32:
|
||||||
|
return lbAny, LineCanBreak, 200
|
||||||
|
|
||||||
|
// LB21.
|
||||||
|
case lbAny | prBA<<32:
|
||||||
|
return lbBA, LineDontBreak, 210
|
||||||
|
case lbAny | prHY<<32:
|
||||||
|
return lbHY, LineDontBreak, 210
|
||||||
|
case lbAny | prNS<<32:
|
||||||
|
return lbNS, LineDontBreak, 210
|
||||||
|
case lbAny | prBB<<32:
|
||||||
|
return lbBB, LineCanBreak, 310
|
||||||
|
case lbBB | prAny<<32:
|
||||||
|
return lbAny, LineDontBreak, 210
|
||||||
|
|
||||||
|
// LB21a.
|
||||||
|
case lbAny | prHL<<32:
|
||||||
|
return lbHL, LineCanBreak, 310
|
||||||
|
case lbHL | prHY<<32:
|
||||||
|
return lbLB21a, LineDontBreak, 210
|
||||||
|
case lbHL | prBA<<32:
|
||||||
|
return lbLB21a, LineDontBreak, 210
|
||||||
|
case lbLB21a | prAny<<32:
|
||||||
|
return lbAny, LineDontBreak, 211
|
||||||
|
|
||||||
|
// LB21b.
|
||||||
|
case lbSY | prHL<<32:
|
||||||
|
return lbHL, LineDontBreak, 212
|
||||||
|
case lbNUSY | prHL<<32:
|
||||||
|
return lbHL, LineDontBreak, 212
|
||||||
|
|
||||||
|
// LB22.
|
||||||
|
case lbAny | prIN<<32:
|
||||||
|
return lbAny, LineDontBreak, 220
|
||||||
|
|
||||||
|
// LB23.
|
||||||
|
case lbAny | prAL<<32:
|
||||||
|
return lbAL, LineCanBreak, 310
|
||||||
|
case lbAny | prNU<<32:
|
||||||
|
return lbNU, LineCanBreak, 310
|
||||||
|
case lbAL | prNU<<32:
|
||||||
|
return lbNU, LineDontBreak, 230
|
||||||
|
case lbHL | prNU<<32:
|
||||||
|
return lbNU, LineDontBreak, 230
|
||||||
|
case lbNU | prAL<<32:
|
||||||
|
return lbAL, LineDontBreak, 230
|
||||||
|
case lbNU | prHL<<32:
|
||||||
|
return lbHL, LineDontBreak, 230
|
||||||
|
case lbNUNU | prAL<<32:
|
||||||
|
return lbAL, LineDontBreak, 230
|
||||||
|
case lbNUNU | prHL<<32:
|
||||||
|
return lbHL, LineDontBreak, 230
|
||||||
|
|
||||||
|
// LB23a.
|
||||||
|
case lbAny | prPR<<32:
|
||||||
|
return lbPR, LineCanBreak, 310
|
||||||
|
case lbAny | prID<<32:
|
||||||
|
return lbIDEM, LineCanBreak, 310
|
||||||
|
case lbAny | prEB<<32:
|
||||||
|
return lbEB, LineCanBreak, 310
|
||||||
|
case lbAny | prEM<<32:
|
||||||
|
return lbIDEM, LineCanBreak, 310
|
||||||
|
case lbPR | prID<<32:
|
||||||
|
return lbIDEM, LineDontBreak, 231
|
||||||
|
case lbPR | prEB<<32:
|
||||||
|
return lbEB, LineDontBreak, 231
|
||||||
|
case lbPR | prEM<<32:
|
||||||
|
return lbIDEM, LineDontBreak, 231
|
||||||
|
case lbIDEM | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 231
|
||||||
|
case lbEB | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 231
|
||||||
|
|
||||||
|
// LB24.
|
||||||
|
case lbAny | prPO<<32:
|
||||||
|
return lbPO, LineCanBreak, 310
|
||||||
|
case lbPR | prAL<<32:
|
||||||
|
return lbAL, LineDontBreak, 240
|
||||||
|
case lbPR | prHL<<32:
|
||||||
|
return lbHL, LineDontBreak, 240
|
||||||
|
case lbPO | prAL<<32:
|
||||||
|
return lbAL, LineDontBreak, 240
|
||||||
|
case lbPO | prHL<<32:
|
||||||
|
return lbHL, LineDontBreak, 240
|
||||||
|
case lbAL | prPR<<32:
|
||||||
|
return lbPR, LineDontBreak, 240
|
||||||
|
case lbAL | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 240
|
||||||
|
case lbHL | prPR<<32:
|
||||||
|
return lbPR, LineDontBreak, 240
|
||||||
|
case lbHL | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 240
|
||||||
|
|
||||||
|
// LB25 (simple transitions).
|
||||||
|
case lbPR | prNU<<32:
|
||||||
|
return lbNU, LineDontBreak, 250
|
||||||
|
case lbPO | prNU<<32:
|
||||||
|
return lbNU, LineDontBreak, 250
|
||||||
|
case lbOP | prNU<<32:
|
||||||
|
return lbNU, LineDontBreak, 250
|
||||||
|
case lbHY | prNU<<32:
|
||||||
|
return lbNU, LineDontBreak, 250
|
||||||
|
case lbNU | prNU<<32:
|
||||||
|
return lbNUNU, LineDontBreak, 250
|
||||||
|
case lbNU | prSY<<32:
|
||||||
|
return lbNUSY, LineDontBreak, 250
|
||||||
|
case lbNU | prIS<<32:
|
||||||
|
return lbNUIS, LineDontBreak, 250
|
||||||
|
case lbNUNU | prNU<<32:
|
||||||
|
return lbNUNU, LineDontBreak, 250
|
||||||
|
case lbNUNU | prSY<<32:
|
||||||
|
return lbNUSY, LineDontBreak, 250
|
||||||
|
case lbNUNU | prIS<<32:
|
||||||
|
return lbNUIS, LineDontBreak, 250
|
||||||
|
case lbNUSY | prNU<<32:
|
||||||
|
return lbNUNU, LineDontBreak, 250
|
||||||
|
case lbNUSY | prSY<<32:
|
||||||
|
return lbNUSY, LineDontBreak, 250
|
||||||
|
case lbNUSY | prIS<<32:
|
||||||
|
return lbNUIS, LineDontBreak, 250
|
||||||
|
case lbNUIS | prNU<<32:
|
||||||
|
return lbNUNU, LineDontBreak, 250
|
||||||
|
case lbNUIS | prSY<<32:
|
||||||
|
return lbNUSY, LineDontBreak, 250
|
||||||
|
case lbNUIS | prIS<<32:
|
||||||
|
return lbNUIS, LineDontBreak, 250
|
||||||
|
case lbNU | prCL<<32:
|
||||||
|
return lbNUCL, LineDontBreak, 250
|
||||||
|
case lbNU | prCP<<32:
|
||||||
|
return lbNUCP, LineDontBreak, 250
|
||||||
|
case lbNUNU | prCL<<32:
|
||||||
|
return lbNUCL, LineDontBreak, 250
|
||||||
|
case lbNUNU | prCP<<32:
|
||||||
|
return lbNUCP, LineDontBreak, 250
|
||||||
|
case lbNUSY | prCL<<32:
|
||||||
|
return lbNUCL, LineDontBreak, 250
|
||||||
|
case lbNUSY | prCP<<32:
|
||||||
|
return lbNUCP, LineDontBreak, 250
|
||||||
|
case lbNUIS | prCL<<32:
|
||||||
|
return lbNUCL, LineDontBreak, 250
|
||||||
|
case lbNUIS | prCP<<32:
|
||||||
|
return lbNUCP, LineDontBreak, 250
|
||||||
|
case lbNU | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 250
|
||||||
|
case lbNUNU | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 250
|
||||||
|
case lbNUSY | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 250
|
||||||
|
case lbNUIS | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 250
|
||||||
|
case lbNUCL | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 250
|
||||||
|
case lbNUCP | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 250
|
||||||
|
case lbNU | prPR<<32:
|
||||||
|
return lbPR, LineDontBreak, 250
|
||||||
|
case lbNUNU | prPR<<32:
|
||||||
|
return lbPR, LineDontBreak, 250
|
||||||
|
case lbNUSY | prPR<<32:
|
||||||
|
return lbPR, LineDontBreak, 250
|
||||||
|
case lbNUIS | prPR<<32:
|
||||||
|
return lbPR, LineDontBreak, 250
|
||||||
|
case lbNUCL | prPR<<32:
|
||||||
|
return lbPR, LineDontBreak, 250
|
||||||
|
case lbNUCP | prPR<<32:
|
||||||
|
return lbPR, LineDontBreak, 250
|
||||||
|
|
||||||
|
// LB26.
|
||||||
|
case lbAny | prJL<<32:
|
||||||
|
return lbJL, LineCanBreak, 310
|
||||||
|
case lbAny | prJV<<32:
|
||||||
|
return lbJV, LineCanBreak, 310
|
||||||
|
case lbAny | prJT<<32:
|
||||||
|
return lbJT, LineCanBreak, 310
|
||||||
|
case lbAny | prH2<<32:
|
||||||
|
return lbH2, LineCanBreak, 310
|
||||||
|
case lbAny | prH3<<32:
|
||||||
|
return lbH3, LineCanBreak, 310
|
||||||
|
case lbJL | prJL<<32:
|
||||||
|
return lbJL, LineDontBreak, 260
|
||||||
|
case lbJL | prJV<<32:
|
||||||
|
return lbJV, LineDontBreak, 260
|
||||||
|
case lbJL | prH2<<32:
|
||||||
|
return lbH2, LineDontBreak, 260
|
||||||
|
case lbJL | prH3<<32:
|
||||||
|
return lbH3, LineDontBreak, 260
|
||||||
|
case lbJV | prJV<<32:
|
||||||
|
return lbJV, LineDontBreak, 260
|
||||||
|
case lbJV | prJT<<32:
|
||||||
|
return lbJT, LineDontBreak, 260
|
||||||
|
case lbH2 | prJV<<32:
|
||||||
|
return lbJV, LineDontBreak, 260
|
||||||
|
case lbH2 | prJT<<32:
|
||||||
|
return lbJT, LineDontBreak, 260
|
||||||
|
case lbJT | prJT<<32:
|
||||||
|
return lbJT, LineDontBreak, 260
|
||||||
|
case lbH3 | prJT<<32:
|
||||||
|
return lbJT, LineDontBreak, 260
|
||||||
|
|
||||||
|
// LB27.
|
||||||
|
case lbJL | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 270
|
||||||
|
case lbJV | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 270
|
||||||
|
case lbJT | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 270
|
||||||
|
case lbH2 | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 270
|
||||||
|
case lbH3 | prPO<<32:
|
||||||
|
return lbPO, LineDontBreak, 270
|
||||||
|
case lbPR | prJL<<32:
|
||||||
|
return lbJL, LineDontBreak, 270
|
||||||
|
case lbPR | prJV<<32:
|
||||||
|
return lbJV, LineDontBreak, 270
|
||||||
|
case lbPR | prJT<<32:
|
||||||
|
return lbJT, LineDontBreak, 270
|
||||||
|
case lbPR | prH2<<32:
|
||||||
|
return lbH2, LineDontBreak, 270
|
||||||
|
case lbPR | prH3<<32:
|
||||||
|
return lbH3, LineDontBreak, 270
|
||||||
|
|
||||||
|
// LB28.
|
||||||
|
case lbAL | prAL<<32:
|
||||||
|
return lbAL, LineDontBreak, 280
|
||||||
|
case lbAL | prHL<<32:
|
||||||
|
return lbHL, LineDontBreak, 280
|
||||||
|
case lbHL | prAL<<32:
|
||||||
|
return lbAL, LineDontBreak, 280
|
||||||
|
case lbHL | prHL<<32:
|
||||||
|
return lbHL, LineDontBreak, 280
|
||||||
|
|
||||||
|
// LB29.
|
||||||
|
case lbIS | prAL<<32:
|
||||||
|
return lbAL, LineDontBreak, 290
|
||||||
|
case lbIS | prHL<<32:
|
||||||
|
return lbHL, LineDontBreak, 290
|
||||||
|
case lbNUIS | prAL<<32:
|
||||||
|
return lbAL, LineDontBreak, 290
|
||||||
|
case lbNUIS | prHL<<32:
|
||||||
|
return lbHL, LineDontBreak, 290
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1, -1, -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// transitionLineBreakState determines the new state of the line break parser
|
||||||
|
// given the current state and the next code point. It also returns the type of
|
||||||
|
// line break: LineDontBreak, LineCanBreak, or LineMustBreak. If more than one
|
||||||
|
// code point is needed to determine the new state, the byte slice or the string
|
||||||
|
// starting after rune "r" can be used (whichever is not nil or empty) for
|
||||||
|
// further lookups.
|
||||||
|
func transitionLineBreakState(state int, r rune, b []byte, str string) (newState int, lineBreak int) {
|
||||||
|
// Determine the property of the next character.
|
||||||
|
nextProperty, generalCategory := propertyLineBreak(r)
|
||||||
|
|
||||||
|
// Prepare.
|
||||||
|
var forceNoBreak, isCPeaFWH bool
|
||||||
|
if state >= 0 && state&lbCPeaFWHBit != 0 {
|
||||||
|
isCPeaFWH = true // LB30: CP but ea is not F, W, or H.
|
||||||
|
state = state &^ lbCPeaFWHBit
|
||||||
|
}
|
||||||
|
if state >= 0 && state&lbZWJBit != 0 {
|
||||||
|
state = state &^ lbZWJBit // Extract zero-width joiner bit.
|
||||||
|
forceNoBreak = true // LB8a.
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
// Transition into LB30.
|
||||||
|
if newState == lbCP || newState == lbNUCP {
|
||||||
|
ea := propertyEastAsianWidth(r)
|
||||||
|
if ea != prF && ea != prW && ea != prH {
|
||||||
|
newState |= lbCPeaFWHBit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override break.
|
||||||
|
if forceNoBreak {
|
||||||
|
lineBreak = LineDontBreak
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// LB1.
|
||||||
|
if nextProperty == prAI || nextProperty == prSG || nextProperty == prXX {
|
||||||
|
nextProperty = prAL
|
||||||
|
} else if nextProperty == prSA {
|
||||||
|
if generalCategory == gcMn || generalCategory == gcMc {
|
||||||
|
nextProperty = prCM
|
||||||
|
} else {
|
||||||
|
nextProperty = prAL
|
||||||
|
}
|
||||||
|
} else if nextProperty == prCJ {
|
||||||
|
nextProperty = prNS
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combining marks.
|
||||||
|
if nextProperty == prZWJ || nextProperty == prCM {
|
||||||
|
var bit int
|
||||||
|
if nextProperty == prZWJ {
|
||||||
|
bit = lbZWJBit
|
||||||
|
}
|
||||||
|
mustBreakState := state < 0 || state == lbBK || state == lbCR || state == lbLF || state == lbNL
|
||||||
|
if !mustBreakState && state != lbSP && state != lbZW && state != lbQUSP && state != lbCLCPSP && state != lbB2SP {
|
||||||
|
// LB9.
|
||||||
|
return state | bit, LineDontBreak
|
||||||
|
} else {
|
||||||
|
// LB10.
|
||||||
|
if mustBreakState {
|
||||||
|
return lbAL | bit, LineMustBreak
|
||||||
|
}
|
||||||
|
return lbAL | bit, LineCanBreak
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the applicable transition in the table.
|
||||||
|
var rule int
|
||||||
|
newState, lineBreak, rule = lbTransitions(state, nextProperty)
|
||||||
|
if newState < 0 {
|
||||||
|
// No specific transition found. Try the less specific ones.
|
||||||
|
anyPropProp, anyPropLineBreak, anyPropRule := lbTransitions(state, prAny)
|
||||||
|
anyStateProp, anyStateLineBreak, anyStateRule := lbTransitions(lbAny, nextProperty)
|
||||||
|
if anyPropProp >= 0 && anyStateProp >= 0 {
|
||||||
|
// Both apply. We'll use a mix (see comments for grTransitions).
|
||||||
|
newState, lineBreak, rule = anyStateProp, anyStateLineBreak, anyStateRule
|
||||||
|
if anyPropRule < anyStateRule {
|
||||||
|
lineBreak, rule = anyPropLineBreak, anyPropRule
|
||||||
|
}
|
||||||
|
} else if anyPropProp >= 0 {
|
||||||
|
// We only have a specific state.
|
||||||
|
newState, lineBreak, rule = anyPropProp, anyPropLineBreak, anyPropRule
|
||||||
|
// This branch will probably never be reached because okAnyState will
|
||||||
|
// always be true given the current transition map. But we keep it here
|
||||||
|
// for future modifications to the transition map where this may not be
|
||||||
|
// true anymore.
|
||||||
|
} else if anyStateProp >= 0 {
|
||||||
|
// We only have a specific property.
|
||||||
|
newState, lineBreak, rule = anyStateProp, anyStateLineBreak, anyStateRule
|
||||||
|
} else {
|
||||||
|
// No known transition. LB31: ALL ÷ ALL.
|
||||||
|
newState, lineBreak, rule = lbAny, LineCanBreak, 310
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LB12a.
|
||||||
|
if rule > 121 &&
|
||||||
|
nextProperty == prGL &&
|
||||||
|
(state != lbSP && state != lbBA && state != lbHY && state != lbLB21a && state != lbQUSP && state != lbCLCPSP && state != lbB2SP) {
|
||||||
|
return lbGL, LineDontBreak
|
||||||
|
}
|
||||||
|
|
||||||
|
// LB13.
|
||||||
|
if rule > 130 && state != lbNU && state != lbNUNU {
|
||||||
|
switch nextProperty {
|
||||||
|
case prCL:
|
||||||
|
return lbCL, LineDontBreak
|
||||||
|
case prCP:
|
||||||
|
return lbCP, LineDontBreak
|
||||||
|
case prIS:
|
||||||
|
return lbIS, LineDontBreak
|
||||||
|
case prSY:
|
||||||
|
return lbSY, LineDontBreak
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LB25 (look ahead).
|
||||||
|
if rule > 250 &&
|
||||||
|
(state == lbPR || state == lbPO) &&
|
||||||
|
nextProperty == prOP || nextProperty == prHY {
|
||||||
|
var r rune
|
||||||
|
if b != nil { // Byte slice version.
|
||||||
|
r, _ = utf8.DecodeRune(b)
|
||||||
|
} else { // String version.
|
||||||
|
r, _ = utf8.DecodeRuneInString(str)
|
||||||
|
}
|
||||||
|
if r != utf8.RuneError {
|
||||||
|
pr, _ := propertyLineBreak(r)
|
||||||
|
if pr == prNU {
|
||||||
|
return lbNU, LineDontBreak
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LB30 (part one).
|
||||||
|
if rule > 300 {
|
||||||
|
if (state == lbAL || state == lbHL || state == lbNU || state == lbNUNU) && nextProperty == prOP {
|
||||||
|
ea := propertyEastAsianWidth(r)
|
||||||
|
if ea != prF && ea != prW && ea != prH {
|
||||||
|
return lbOP, LineDontBreak
|
||||||
|
}
|
||||||
|
} else if isCPeaFWH {
|
||||||
|
switch nextProperty {
|
||||||
|
case prAL:
|
||||||
|
return lbAL, LineDontBreak
|
||||||
|
case prHL:
|
||||||
|
return lbHL, LineDontBreak
|
||||||
|
case prNU:
|
||||||
|
return lbNU, LineDontBreak
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LB30a.
|
||||||
|
if newState == lbAny && nextProperty == prRI {
|
||||||
|
if state != lbOddRI && state != lbEvenRI { // Includes state == -1.
|
||||||
|
// Transition into the first RI.
|
||||||
|
return lbOddRI, lineBreak
|
||||||
|
}
|
||||||
|
if state == lbOddRI {
|
||||||
|
// Don't break pairs of Regional Indicators.
|
||||||
|
return lbEvenRI, LineDontBreak
|
||||||
|
}
|
||||||
|
return lbOddRI, lineBreak
|
||||||
|
}
|
||||||
|
|
||||||
|
// LB30b.
|
||||||
|
if rule > 302 {
|
||||||
|
if nextProperty == prEM {
|
||||||
|
if state == lbEB || state == lbExtPicCn {
|
||||||
|
return prAny, LineDontBreak
|
||||||
|
}
|
||||||
|
}
|
||||||
|
graphemeProperty := propertyGraphemes(r)
|
||||||
|
if graphemeProperty == prExtendedPictographic && generalCategory == gcCn {
|
||||||
|
return lbExtPicCn, LineCanBreak
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,208 @@
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
// The Unicode properties as used in the various parsers. Only the ones needed
|
||||||
|
// in the context of this package are included.
|
||||||
|
const (
|
||||||
|
prXX = 0 // Same as prAny.
|
||||||
|
prAny = iota // prAny must be 0.
|
||||||
|
prPrepend // Grapheme properties must come first, to reduce the number of bits stored in the state vector.
|
||||||
|
prCR
|
||||||
|
prLF
|
||||||
|
prControl
|
||||||
|
prExtend
|
||||||
|
prRegionalIndicator
|
||||||
|
prSpacingMark
|
||||||
|
prL
|
||||||
|
prV
|
||||||
|
prT
|
||||||
|
prLV
|
||||||
|
prLVT
|
||||||
|
prZWJ
|
||||||
|
prExtendedPictographic
|
||||||
|
prNewline
|
||||||
|
prWSegSpace
|
||||||
|
prDoubleQuote
|
||||||
|
prSingleQuote
|
||||||
|
prMidNumLet
|
||||||
|
prNumeric
|
||||||
|
prMidLetter
|
||||||
|
prMidNum
|
||||||
|
prExtendNumLet
|
||||||
|
prALetter
|
||||||
|
prFormat
|
||||||
|
prHebrewLetter
|
||||||
|
prKatakana
|
||||||
|
prSp
|
||||||
|
prSTerm
|
||||||
|
prClose
|
||||||
|
prSContinue
|
||||||
|
prATerm
|
||||||
|
prUpper
|
||||||
|
prLower
|
||||||
|
prSep
|
||||||
|
prOLetter
|
||||||
|
prCM
|
||||||
|
prBA
|
||||||
|
prBK
|
||||||
|
prSP
|
||||||
|
prEX
|
||||||
|
prQU
|
||||||
|
prAL
|
||||||
|
prPR
|
||||||
|
prPO
|
||||||
|
prOP
|
||||||
|
prCP
|
||||||
|
prIS
|
||||||
|
prHY
|
||||||
|
prSY
|
||||||
|
prNU
|
||||||
|
prCL
|
||||||
|
prNL
|
||||||
|
prGL
|
||||||
|
prAI
|
||||||
|
prBB
|
||||||
|
prHL
|
||||||
|
prSA
|
||||||
|
prJL
|
||||||
|
prJV
|
||||||
|
prJT
|
||||||
|
prNS
|
||||||
|
prZW
|
||||||
|
prB2
|
||||||
|
prIN
|
||||||
|
prWJ
|
||||||
|
prID
|
||||||
|
prEB
|
||||||
|
prCJ
|
||||||
|
prH2
|
||||||
|
prH3
|
||||||
|
prSG
|
||||||
|
prCB
|
||||||
|
prRI
|
||||||
|
prEM
|
||||||
|
prN
|
||||||
|
prNa
|
||||||
|
prA
|
||||||
|
prW
|
||||||
|
prH
|
||||||
|
prF
|
||||||
|
prEmojiPresentation
|
||||||
|
)
|
||||||
|
|
||||||
|
// Unicode General Categories. Only the ones needed in the context of this
|
||||||
|
// package are included.
|
||||||
|
const (
|
||||||
|
gcNone = iota // gcNone must be 0.
|
||||||
|
gcCc
|
||||||
|
gcZs
|
||||||
|
gcPo
|
||||||
|
gcSc
|
||||||
|
gcPs
|
||||||
|
gcPe
|
||||||
|
gcSm
|
||||||
|
gcPd
|
||||||
|
gcNd
|
||||||
|
gcLu
|
||||||
|
gcSk
|
||||||
|
gcPc
|
||||||
|
gcLl
|
||||||
|
gcSo
|
||||||
|
gcLo
|
||||||
|
gcPi
|
||||||
|
gcCf
|
||||||
|
gcNo
|
||||||
|
gcPf
|
||||||
|
gcLC
|
||||||
|
gcLm
|
||||||
|
gcMn
|
||||||
|
gcMe
|
||||||
|
gcMc
|
||||||
|
gcNl
|
||||||
|
gcZl
|
||||||
|
gcZp
|
||||||
|
gcCn
|
||||||
|
gcCs
|
||||||
|
gcCo
|
||||||
|
)
|
||||||
|
|
||||||
|
// Special code points.
|
||||||
|
const (
|
||||||
|
vs15 = 0xfe0e // Variation Selector-15 (text presentation)
|
||||||
|
vs16 = 0xfe0f // Variation Selector-16 (emoji presentation)
|
||||||
|
)
|
||||||
|
|
||||||
|
// propertySearch performs a binary search on a property slice and returns the
|
||||||
|
// entry whose range (start = first array element, end = second array element)
|
||||||
|
// includes r, or an array of 0's if no such entry was found.
|
||||||
|
func propertySearch[E interface{ [3]int | [4]int }](dictionary []E, r rune) (result E) {
|
||||||
|
// Run a binary search.
|
||||||
|
from := 0
|
||||||
|
to := len(dictionary)
|
||||||
|
for to > from {
|
||||||
|
middle := (from + to) / 2
|
||||||
|
cpRange := dictionary[middle]
|
||||||
|
if int(r) < cpRange[0] {
|
||||||
|
to = middle
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if int(r) > cpRange[1] {
|
||||||
|
from = middle + 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return cpRange
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// property returns the Unicode property value (see constants above) of the
|
||||||
|
// given code point.
|
||||||
|
func property(dictionary [][3]int, r rune) int {
|
||||||
|
return propertySearch(dictionary, r)[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
// propertyLineBreak returns the Unicode property value and General Category
|
||||||
|
// (see constants above) of the given code point, as listed in the line break
|
||||||
|
// code points table, while fast tracking ASCII digits and letters.
|
||||||
|
func propertyLineBreak(r rune) (property, generalCategory int) {
|
||||||
|
if r >= 'a' && r <= 'z' {
|
||||||
|
return prAL, gcLl
|
||||||
|
}
|
||||||
|
if r >= 'A' && r <= 'Z' {
|
||||||
|
return prAL, gcLu
|
||||||
|
}
|
||||||
|
if r >= '0' && r <= '9' {
|
||||||
|
return prNU, gcNd
|
||||||
|
}
|
||||||
|
entry := propertySearch(lineBreakCodePoints, r)
|
||||||
|
return entry[2], entry[3]
|
||||||
|
}
|
||||||
|
|
||||||
|
// propertyGraphemes returns the Unicode grapheme cluster property value of the
|
||||||
|
// given code point while fast tracking ASCII characters.
|
||||||
|
func propertyGraphemes(r rune) int {
|
||||||
|
if r >= 0x20 && r <= 0x7e {
|
||||||
|
return prAny
|
||||||
|
}
|
||||||
|
if r == 0x0a {
|
||||||
|
return prLF
|
||||||
|
}
|
||||||
|
if r == 0x0d {
|
||||||
|
return prCR
|
||||||
|
}
|
||||||
|
if r >= 0 && r <= 0x1f || r == 0x7f {
|
||||||
|
return prControl
|
||||||
|
}
|
||||||
|
return property(graphemeCodePoints, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// propertyEastAsianWidth returns the Unicode East Asian Width property value of
|
||||||
|
// the given code point while fast tracking ASCII characters.
|
||||||
|
func propertyEastAsianWidth(r rune) int {
|
||||||
|
if r >= 0x20 && r <= 0x7e {
|
||||||
|
return prNa
|
||||||
|
}
|
||||||
|
if r >= 0 && r <= 0x1f || r == 0x7f {
|
||||||
|
return prN
|
||||||
|
}
|
||||||
|
return property(eastAsianWidth, r)
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
// FirstSentence returns the first sentence found in the given byte slice
|
||||||
|
// according to the rules of [Unicode Standard Annex #29, Sentence Boundaries].
|
||||||
|
// This function can be called continuously to extract all sentences from a byte
|
||||||
|
// slice, as illustrated in the example below.
|
||||||
|
//
|
||||||
|
// If you don't know the current state, for example when calling the function
|
||||||
|
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||||
|
// and rest slice returned by the previous call.
|
||||||
|
//
|
||||||
|
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||||
|
// after the last byte of the identified sentence. If the length of the "rest"
|
||||||
|
// slice is 0, the entire byte slice "b" has been processed. The "sentence" byte
|
||||||
|
// slice is the sub-slice of the input slice containing the identified sentence.
|
||||||
|
//
|
||||||
|
// Given an empty byte slice "b", the function returns nil values.
|
||||||
|
//
|
||||||
|
// [Unicode Standard Annex #29, Sentence Boundaries]: http://unicode.org/reports/tr29/#Sentence_Boundaries
|
||||||
|
func FirstSentence(b []byte, state int) (sentence, rest []byte, newState int) {
|
||||||
|
// An empty byte slice returns nothing.
|
||||||
|
if len(b) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the first rune.
|
||||||
|
r, length := utf8.DecodeRune(b)
|
||||||
|
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||||
|
return b, nil, sbAny
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't know the state, determine it now.
|
||||||
|
if state < 0 {
|
||||||
|
state, _ = transitionSentenceBreakState(state, r, b[length:], "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition until we find a boundary.
|
||||||
|
var boundary bool
|
||||||
|
for {
|
||||||
|
r, l := utf8.DecodeRune(b[length:])
|
||||||
|
state, boundary = transitionSentenceBreakState(state, r, b[length+l:], "")
|
||||||
|
|
||||||
|
if boundary {
|
||||||
|
return b[:length], b[length:], state
|
||||||
|
}
|
||||||
|
|
||||||
|
length += l
|
||||||
|
if len(b) <= length {
|
||||||
|
return b, nil, sbAny
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstSentenceInString is like [FirstSentence] but its input and outputs are
|
||||||
|
// strings.
|
||||||
|
func FirstSentenceInString(str string, state int) (sentence, rest string, newState int) {
|
||||||
|
// An empty byte slice returns nothing.
|
||||||
|
if len(str) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the first rune.
|
||||||
|
r, length := utf8.DecodeRuneInString(str)
|
||||||
|
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||||
|
return str, "", sbAny
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't know the state, determine it now.
|
||||||
|
if state < 0 {
|
||||||
|
state, _ = transitionSentenceBreakState(state, r, nil, str[length:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition until we find a boundary.
|
||||||
|
var boundary bool
|
||||||
|
for {
|
||||||
|
r, l := utf8.DecodeRuneInString(str[length:])
|
||||||
|
state, boundary = transitionSentenceBreakState(state, r, nil, str[length+l:])
|
||||||
|
|
||||||
|
if boundary {
|
||||||
|
return str[:length], str[length:], state
|
||||||
|
}
|
||||||
|
|
||||||
|
length += l
|
||||||
|
if len(str) <= length {
|
||||||
|
return str, "", sbAny
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2845
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/sentenceproperties.go
generated
vendored
Normal file
2845
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/sentenceproperties.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,276 @@
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
// The states of the sentence break parser.
|
||||||
|
const (
|
||||||
|
sbAny = iota
|
||||||
|
sbCR
|
||||||
|
sbParaSep
|
||||||
|
sbATerm
|
||||||
|
sbUpper
|
||||||
|
sbLower
|
||||||
|
sbSB7
|
||||||
|
sbSB8Close
|
||||||
|
sbSB8Sp
|
||||||
|
sbSTerm
|
||||||
|
sbSB8aClose
|
||||||
|
sbSB8aSp
|
||||||
|
)
|
||||||
|
|
||||||
|
// sbTransitions implements the sentence break parser's state transitions. It's
|
||||||
|
// anologous to [grTransitions], see comments there for details.
|
||||||
|
//
|
||||||
|
// Unicode version 15.0.0.
|
||||||
|
func sbTransitions(state, prop int) (newState int, sentenceBreak bool, rule int) {
|
||||||
|
switch uint64(state) | uint64(prop)<<32 {
|
||||||
|
// SB3.
|
||||||
|
case sbAny | prCR<<32:
|
||||||
|
return sbCR, false, 9990
|
||||||
|
case sbCR | prLF<<32:
|
||||||
|
return sbParaSep, false, 30
|
||||||
|
|
||||||
|
// SB4.
|
||||||
|
case sbAny | prSep<<32:
|
||||||
|
return sbParaSep, false, 9990
|
||||||
|
case sbAny | prLF<<32:
|
||||||
|
return sbParaSep, false, 9990
|
||||||
|
case sbParaSep | prAny<<32:
|
||||||
|
return sbAny, true, 40
|
||||||
|
case sbCR | prAny<<32:
|
||||||
|
return sbAny, true, 40
|
||||||
|
|
||||||
|
// SB6.
|
||||||
|
case sbAny | prATerm<<32:
|
||||||
|
return sbATerm, false, 9990
|
||||||
|
case sbATerm | prNumeric<<32:
|
||||||
|
return sbAny, false, 60
|
||||||
|
case sbSB7 | prNumeric<<32:
|
||||||
|
return sbAny, false, 60 // Because ATerm also appears in SB7.
|
||||||
|
|
||||||
|
// SB7.
|
||||||
|
case sbAny | prUpper<<32:
|
||||||
|
return sbUpper, false, 9990
|
||||||
|
case sbAny | prLower<<32:
|
||||||
|
return sbLower, false, 9990
|
||||||
|
case sbUpper | prATerm<<32:
|
||||||
|
return sbSB7, false, 70
|
||||||
|
case sbLower | prATerm<<32:
|
||||||
|
return sbSB7, false, 70
|
||||||
|
case sbSB7 | prUpper<<32:
|
||||||
|
return sbUpper, false, 70
|
||||||
|
|
||||||
|
// SB8a.
|
||||||
|
case sbAny | prSTerm<<32:
|
||||||
|
return sbSTerm, false, 9990
|
||||||
|
case sbATerm | prSContinue<<32:
|
||||||
|
return sbAny, false, 81
|
||||||
|
case sbATerm | prATerm<<32:
|
||||||
|
return sbATerm, false, 81
|
||||||
|
case sbATerm | prSTerm<<32:
|
||||||
|
return sbSTerm, false, 81
|
||||||
|
case sbSB7 | prSContinue<<32:
|
||||||
|
return sbAny, false, 81
|
||||||
|
case sbSB7 | prATerm<<32:
|
||||||
|
return sbATerm, false, 81
|
||||||
|
case sbSB7 | prSTerm<<32:
|
||||||
|
return sbSTerm, false, 81
|
||||||
|
case sbSB8Close | prSContinue<<32:
|
||||||
|
return sbAny, false, 81
|
||||||
|
case sbSB8Close | prATerm<<32:
|
||||||
|
return sbATerm, false, 81
|
||||||
|
case sbSB8Close | prSTerm<<32:
|
||||||
|
return sbSTerm, false, 81
|
||||||
|
case sbSB8Sp | prSContinue<<32:
|
||||||
|
return sbAny, false, 81
|
||||||
|
case sbSB8Sp | prATerm<<32:
|
||||||
|
return sbATerm, false, 81
|
||||||
|
case sbSB8Sp | prSTerm<<32:
|
||||||
|
return sbSTerm, false, 81
|
||||||
|
case sbSTerm | prSContinue<<32:
|
||||||
|
return sbAny, false, 81
|
||||||
|
case sbSTerm | prATerm<<32:
|
||||||
|
return sbATerm, false, 81
|
||||||
|
case sbSTerm | prSTerm<<32:
|
||||||
|
return sbSTerm, false, 81
|
||||||
|
case sbSB8aClose | prSContinue<<32:
|
||||||
|
return sbAny, false, 81
|
||||||
|
case sbSB8aClose | prATerm<<32:
|
||||||
|
return sbATerm, false, 81
|
||||||
|
case sbSB8aClose | prSTerm<<32:
|
||||||
|
return sbSTerm, false, 81
|
||||||
|
case sbSB8aSp | prSContinue<<32:
|
||||||
|
return sbAny, false, 81
|
||||||
|
case sbSB8aSp | prATerm<<32:
|
||||||
|
return sbATerm, false, 81
|
||||||
|
case sbSB8aSp | prSTerm<<32:
|
||||||
|
return sbSTerm, false, 81
|
||||||
|
|
||||||
|
// SB9.
|
||||||
|
case sbATerm | prClose<<32:
|
||||||
|
return sbSB8Close, false, 90
|
||||||
|
case sbSB7 | prClose<<32:
|
||||||
|
return sbSB8Close, false, 90
|
||||||
|
case sbSB8Close | prClose<<32:
|
||||||
|
return sbSB8Close, false, 90
|
||||||
|
case sbATerm | prSp<<32:
|
||||||
|
return sbSB8Sp, false, 90
|
||||||
|
case sbSB7 | prSp<<32:
|
||||||
|
return sbSB8Sp, false, 90
|
||||||
|
case sbSB8Close | prSp<<32:
|
||||||
|
return sbSB8Sp, false, 90
|
||||||
|
case sbSTerm | prClose<<32:
|
||||||
|
return sbSB8aClose, false, 90
|
||||||
|
case sbSB8aClose | prClose<<32:
|
||||||
|
return sbSB8aClose, false, 90
|
||||||
|
case sbSTerm | prSp<<32:
|
||||||
|
return sbSB8aSp, false, 90
|
||||||
|
case sbSB8aClose | prSp<<32:
|
||||||
|
return sbSB8aSp, false, 90
|
||||||
|
case sbATerm | prSep<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbATerm | prCR<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbATerm | prLF<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSB7 | prSep<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSB7 | prCR<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSB7 | prLF<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSB8Close | prSep<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSB8Close | prCR<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSB8Close | prLF<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSTerm | prSep<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSTerm | prCR<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSTerm | prLF<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSB8aClose | prSep<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSB8aClose | prCR<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
case sbSB8aClose | prLF<<32:
|
||||||
|
return sbParaSep, false, 90
|
||||||
|
|
||||||
|
// SB10.
|
||||||
|
case sbSB8Sp | prSp<<32:
|
||||||
|
return sbSB8Sp, false, 100
|
||||||
|
case sbSB8aSp | prSp<<32:
|
||||||
|
return sbSB8aSp, false, 100
|
||||||
|
case sbSB8Sp | prSep<<32:
|
||||||
|
return sbParaSep, false, 100
|
||||||
|
case sbSB8Sp | prCR<<32:
|
||||||
|
return sbParaSep, false, 100
|
||||||
|
case sbSB8Sp | prLF<<32:
|
||||||
|
return sbParaSep, false, 100
|
||||||
|
|
||||||
|
// SB11.
|
||||||
|
case sbATerm | prAny<<32:
|
||||||
|
return sbAny, true, 110
|
||||||
|
case sbSB7 | prAny<<32:
|
||||||
|
return sbAny, true, 110
|
||||||
|
case sbSB8Close | prAny<<32:
|
||||||
|
return sbAny, true, 110
|
||||||
|
case sbSB8Sp | prAny<<32:
|
||||||
|
return sbAny, true, 110
|
||||||
|
case sbSTerm | prAny<<32:
|
||||||
|
return sbAny, true, 110
|
||||||
|
case sbSB8aClose | prAny<<32:
|
||||||
|
return sbAny, true, 110
|
||||||
|
case sbSB8aSp | prAny<<32:
|
||||||
|
return sbAny, true, 110
|
||||||
|
// We'll always break after ParaSep due to SB4.
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1, false, -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// transitionSentenceBreakState determines the new state of the sentence break
|
||||||
|
// parser given the current state and the next code point. It also returns
|
||||||
|
// whether a sentence boundary was detected. If more than one code point is
|
||||||
|
// needed to determine the new state, the byte slice or the string starting
|
||||||
|
// after rune "r" can be used (whichever is not nil or empty) for further
|
||||||
|
// lookups.
|
||||||
|
func transitionSentenceBreakState(state int, r rune, b []byte, str string) (newState int, sentenceBreak bool) {
|
||||||
|
// Determine the property of the next character.
|
||||||
|
nextProperty := property(sentenceBreakCodePoints, r)
|
||||||
|
|
||||||
|
// SB5 (Replacing Ignore Rules).
|
||||||
|
if nextProperty == prExtend || nextProperty == prFormat {
|
||||||
|
if state == sbParaSep || state == sbCR {
|
||||||
|
return sbAny, true // Make sure we don't apply SB5 to SB3 or SB4.
|
||||||
|
}
|
||||||
|
if state < 0 {
|
||||||
|
return sbAny, true // SB1.
|
||||||
|
}
|
||||||
|
return state, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the applicable transition in the table.
|
||||||
|
var rule int
|
||||||
|
newState, sentenceBreak, rule = sbTransitions(state, nextProperty)
|
||||||
|
if newState < 0 {
|
||||||
|
// No specific transition found. Try the less specific ones.
|
||||||
|
anyPropState, anyPropProp, anyPropRule := sbTransitions(state, prAny)
|
||||||
|
anyStateState, anyStateProp, anyStateRule := sbTransitions(sbAny, nextProperty)
|
||||||
|
if anyPropState >= 0 && anyStateState >= 0 {
|
||||||
|
// Both apply. We'll use a mix (see comments for grTransitions).
|
||||||
|
newState, sentenceBreak, rule = anyStateState, anyStateProp, anyStateRule
|
||||||
|
if anyPropRule < anyStateRule {
|
||||||
|
sentenceBreak, rule = anyPropProp, anyPropRule
|
||||||
|
}
|
||||||
|
} else if anyPropState >= 0 {
|
||||||
|
// We only have a specific state.
|
||||||
|
newState, sentenceBreak, rule = anyPropState, anyPropProp, anyPropRule
|
||||||
|
// This branch will probably never be reached because okAnyState will
|
||||||
|
// always be true given the current transition map. But we keep it here
|
||||||
|
// for future modifications to the transition map where this may not be
|
||||||
|
// true anymore.
|
||||||
|
} else if anyStateState >= 0 {
|
||||||
|
// We only have a specific property.
|
||||||
|
newState, sentenceBreak, rule = anyStateState, anyStateProp, anyStateRule
|
||||||
|
} else {
|
||||||
|
// No known transition. SB999: Any × Any.
|
||||||
|
newState, sentenceBreak, rule = sbAny, false, 9990
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SB8.
|
||||||
|
if rule > 80 && (state == sbATerm || state == sbSB8Close || state == sbSB8Sp || state == sbSB7) {
|
||||||
|
// Check the right side of the rule.
|
||||||
|
var length int
|
||||||
|
for nextProperty != prOLetter &&
|
||||||
|
nextProperty != prUpper &&
|
||||||
|
nextProperty != prLower &&
|
||||||
|
nextProperty != prSep &&
|
||||||
|
nextProperty != prCR &&
|
||||||
|
nextProperty != prLF &&
|
||||||
|
nextProperty != prATerm &&
|
||||||
|
nextProperty != prSTerm {
|
||||||
|
// Move on to the next rune.
|
||||||
|
if b != nil { // Byte slice version.
|
||||||
|
r, length = utf8.DecodeRune(b)
|
||||||
|
b = b[length:]
|
||||||
|
} else { // String version.
|
||||||
|
r, length = utf8.DecodeRuneInString(str)
|
||||||
|
str = str[length:]
|
||||||
|
}
|
||||||
|
if r == utf8.RuneError {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
nextProperty = property(sentenceBreakCodePoints, r)
|
||||||
|
}
|
||||||
|
if nextProperty == prLower {
|
||||||
|
return sbLower, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,242 @@
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
// The bit masks used to extract boundary information returned by [Step].
|
||||||
|
const (
|
||||||
|
MaskLine = 3
|
||||||
|
MaskWord = 4
|
||||||
|
MaskSentence = 8
|
||||||
|
)
|
||||||
|
|
||||||
|
// The number of bits to shift the boundary information returned by [Step] to
|
||||||
|
// obtain the monospace width of the grapheme cluster.
|
||||||
|
const ShiftWidth = 4
|
||||||
|
|
||||||
|
// The bit positions by which boundary flags are shifted by the [Step] function.
|
||||||
|
// These must correspond to the Mask constants.
|
||||||
|
const (
|
||||||
|
shiftWord = 2
|
||||||
|
shiftSentence = 3
|
||||||
|
// shiftwWidth is ShiftWidth above. No mask as these are always the remaining bits.
|
||||||
|
)
|
||||||
|
|
||||||
|
// The bit positions by which states are shifted by the [Step] function. These
|
||||||
|
// values must ensure state values defined for each of the boundary algorithms
|
||||||
|
// don't overlap (and that they all still fit in a single int). These must
|
||||||
|
// correspond to the Mask constants.
|
||||||
|
const (
|
||||||
|
shiftWordState = 4
|
||||||
|
shiftSentenceState = 9
|
||||||
|
shiftLineState = 13
|
||||||
|
shiftPropState = 21 // No mask as these are always the remaining bits.
|
||||||
|
)
|
||||||
|
|
||||||
|
// The bit mask used to extract the state returned by the [Step] function, after
|
||||||
|
// shifting. These values must correspond to the shift constants.
|
||||||
|
const (
|
||||||
|
maskGraphemeState = 0xf
|
||||||
|
maskWordState = 0x1f
|
||||||
|
maskSentenceState = 0xf
|
||||||
|
maskLineState = 0xff
|
||||||
|
)
|
||||||
|
|
||||||
|
// Step returns the first grapheme cluster (user-perceived character) found in
|
||||||
|
// the given byte slice. It also returns information about the boundary between
|
||||||
|
// that grapheme cluster and the one following it as well as the monospace width
|
||||||
|
// of the grapheme cluster. There are three types of boundary information: word
|
||||||
|
// boundaries, sentence boundaries, and line breaks. This function is therefore
|
||||||
|
// a combination of [FirstGraphemeCluster], [FirstWord], [FirstSentence], and
|
||||||
|
// [FirstLineSegment].
|
||||||
|
//
|
||||||
|
// The "boundaries" return value can be evaluated as follows:
|
||||||
|
//
|
||||||
|
// - boundaries&MaskWord != 0: The boundary is a word boundary.
|
||||||
|
// - boundaries&MaskWord == 0: The boundary is not a word boundary.
|
||||||
|
// - boundaries&MaskSentence != 0: The boundary is a sentence boundary.
|
||||||
|
// - boundaries&MaskSentence == 0: The boundary is not a sentence boundary.
|
||||||
|
// - boundaries&MaskLine == LineDontBreak: You must not break the line at the
|
||||||
|
// boundary.
|
||||||
|
// - boundaries&MaskLine == LineMustBreak: You must break the line at the
|
||||||
|
// boundary.
|
||||||
|
// - boundaries&MaskLine == LineCanBreak: You may or may not break the line at
|
||||||
|
// the boundary.
|
||||||
|
// - boundaries >> ShiftWidth: The width of the grapheme cluster for most
|
||||||
|
// monospace fonts where a value of 1 represents one character cell.
|
||||||
|
//
|
||||||
|
// This function can be called continuously to extract all grapheme clusters
|
||||||
|
// from a byte slice, as illustrated in the examples below.
|
||||||
|
//
|
||||||
|
// If you don't know which state to pass, for example when calling the function
|
||||||
|
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||||
|
// and rest slice returned by the previous call.
|
||||||
|
//
|
||||||
|
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||||
|
// after the last byte of the identified grapheme cluster. If the length of the
|
||||||
|
// "rest" slice is 0, the entire byte slice "b" has been processed. The
|
||||||
|
// "cluster" byte slice is the sub-slice of the input slice containing the
|
||||||
|
// first identified grapheme cluster.
|
||||||
|
//
|
||||||
|
// Given an empty byte slice "b", the function returns nil values.
|
||||||
|
//
|
||||||
|
// While slightly less convenient than using the Graphemes class, this function
|
||||||
|
// has much better performance and makes no allocations. It lends itself well to
|
||||||
|
// large byte slices.
|
||||||
|
//
|
||||||
|
// Note that in accordance with [UAX #14 LB3], the final segment will end with
|
||||||
|
// a mandatory line break (boundaries&MaskLine == LineMustBreak). You can choose
|
||||||
|
// to ignore this by checking if the length of the "rest" slice is 0 and calling
|
||||||
|
// [HasTrailingLineBreak] or [HasTrailingLineBreakInString] on the last rune.
|
||||||
|
//
|
||||||
|
// [UAX #14 LB3]: https://www.unicode.org/reports/tr14/#Algorithm
|
||||||
|
func Step(b []byte, state int) (cluster, rest []byte, boundaries int, newState int) {
|
||||||
|
// An empty byte slice returns nothing.
|
||||||
|
if len(b) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the first rune.
|
||||||
|
r, length := utf8.DecodeRune(b)
|
||||||
|
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||||
|
var prop int
|
||||||
|
if state < 0 {
|
||||||
|
prop = propertyGraphemes(r)
|
||||||
|
} else {
|
||||||
|
prop = state >> shiftPropState
|
||||||
|
}
|
||||||
|
return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't know the state, determine it now.
|
||||||
|
var graphemeState, wordState, sentenceState, lineState, firstProp int
|
||||||
|
remainder := b[length:]
|
||||||
|
if state < 0 {
|
||||||
|
graphemeState, firstProp, _ = transitionGraphemeState(state, r)
|
||||||
|
wordState, _ = transitionWordBreakState(state, r, remainder, "")
|
||||||
|
sentenceState, _ = transitionSentenceBreakState(state, r, remainder, "")
|
||||||
|
lineState, _ = transitionLineBreakState(state, r, remainder, "")
|
||||||
|
} else {
|
||||||
|
graphemeState = state & maskGraphemeState
|
||||||
|
wordState = (state >> shiftWordState) & maskWordState
|
||||||
|
sentenceState = (state >> shiftSentenceState) & maskSentenceState
|
||||||
|
lineState = (state >> shiftLineState) & maskLineState
|
||||||
|
firstProp = state >> shiftPropState
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition until we find a grapheme cluster boundary.
|
||||||
|
width := runeWidth(r, firstProp)
|
||||||
|
for {
|
||||||
|
var (
|
||||||
|
graphemeBoundary, wordBoundary, sentenceBoundary bool
|
||||||
|
lineBreak, prop int
|
||||||
|
)
|
||||||
|
|
||||||
|
r, l := utf8.DecodeRune(remainder)
|
||||||
|
remainder = b[length+l:]
|
||||||
|
|
||||||
|
graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r)
|
||||||
|
wordState, wordBoundary = transitionWordBreakState(wordState, r, remainder, "")
|
||||||
|
sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, remainder, "")
|
||||||
|
lineState, lineBreak = transitionLineBreakState(lineState, r, remainder, "")
|
||||||
|
|
||||||
|
if graphemeBoundary {
|
||||||
|
boundary := lineBreak | (width << ShiftWidth)
|
||||||
|
if wordBoundary {
|
||||||
|
boundary |= 1 << shiftWord
|
||||||
|
}
|
||||||
|
if sentenceBoundary {
|
||||||
|
boundary |= 1 << shiftSentence
|
||||||
|
}
|
||||||
|
return b[:length], b[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState)
|
||||||
|
}
|
||||||
|
|
||||||
|
if firstProp == prExtendedPictographic {
|
||||||
|
if r == vs15 {
|
||||||
|
width = 1
|
||||||
|
} else if r == vs16 {
|
||||||
|
width = 2
|
||||||
|
}
|
||||||
|
} else if firstProp != prRegionalIndicator && firstProp != prL {
|
||||||
|
width += runeWidth(r, prop)
|
||||||
|
}
|
||||||
|
|
||||||
|
length += l
|
||||||
|
if len(b) <= length {
|
||||||
|
return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StepString is like [Step] but its input and outputs are strings.
|
||||||
|
func StepString(str string, state int) (cluster, rest string, boundaries int, newState int) {
|
||||||
|
// An empty byte slice returns nothing.
|
||||||
|
if len(str) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the first rune.
|
||||||
|
r, length := utf8.DecodeRuneInString(str)
|
||||||
|
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||||
|
prop := propertyGraphemes(r)
|
||||||
|
return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't know the state, determine it now.
|
||||||
|
var graphemeState, wordState, sentenceState, lineState, firstProp int
|
||||||
|
remainder := str[length:]
|
||||||
|
if state < 0 {
|
||||||
|
graphemeState, firstProp, _ = transitionGraphemeState(state, r)
|
||||||
|
wordState, _ = transitionWordBreakState(state, r, nil, remainder)
|
||||||
|
sentenceState, _ = transitionSentenceBreakState(state, r, nil, remainder)
|
||||||
|
lineState, _ = transitionLineBreakState(state, r, nil, remainder)
|
||||||
|
} else {
|
||||||
|
graphemeState = state & maskGraphemeState
|
||||||
|
wordState = (state >> shiftWordState) & maskWordState
|
||||||
|
sentenceState = (state >> shiftSentenceState) & maskSentenceState
|
||||||
|
lineState = (state >> shiftLineState) & maskLineState
|
||||||
|
firstProp = state >> shiftPropState
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition until we find a grapheme cluster boundary.
|
||||||
|
width := runeWidth(r, firstProp)
|
||||||
|
for {
|
||||||
|
var (
|
||||||
|
graphemeBoundary, wordBoundary, sentenceBoundary bool
|
||||||
|
lineBreak, prop int
|
||||||
|
)
|
||||||
|
|
||||||
|
r, l := utf8.DecodeRuneInString(remainder)
|
||||||
|
remainder = str[length+l:]
|
||||||
|
|
||||||
|
graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r)
|
||||||
|
wordState, wordBoundary = transitionWordBreakState(wordState, r, nil, remainder)
|
||||||
|
sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, nil, remainder)
|
||||||
|
lineState, lineBreak = transitionLineBreakState(lineState, r, nil, remainder)
|
||||||
|
|
||||||
|
if graphemeBoundary {
|
||||||
|
boundary := lineBreak | (width << ShiftWidth)
|
||||||
|
if wordBoundary {
|
||||||
|
boundary |= 1 << shiftWord
|
||||||
|
}
|
||||||
|
if sentenceBoundary {
|
||||||
|
boundary |= 1 << shiftSentence
|
||||||
|
}
|
||||||
|
return str[:length], str[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState)
|
||||||
|
}
|
||||||
|
|
||||||
|
if firstProp == prExtendedPictographic {
|
||||||
|
if r == vs15 {
|
||||||
|
width = 1
|
||||||
|
} else if r == vs16 {
|
||||||
|
width = 2
|
||||||
|
}
|
||||||
|
} else if firstProp != prRegionalIndicator && firstProp != prL {
|
||||||
|
width += runeWidth(r, prop)
|
||||||
|
}
|
||||||
|
|
||||||
|
length += l
|
||||||
|
if len(str) <= length {
|
||||||
|
return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
// EastAsianAmbiguousWidth specifies the monospace width for East Asian
|
||||||
|
// characters classified as Ambiguous. The default is 1 but some rare fonts
|
||||||
|
// render them with a width of 2.
|
||||||
|
var EastAsianAmbiguousWidth = 1
|
||||||
|
|
||||||
|
// runeWidth returns the monospace width for the given rune. The provided
|
||||||
|
// grapheme property is a value mapped by the [graphemeCodePoints] table.
|
||||||
|
//
|
||||||
|
// Every rune has a width of 1, except for runes with the following properties
|
||||||
|
// (evaluated in this order):
|
||||||
|
//
|
||||||
|
// - Control, CR, LF, Extend, ZWJ: Width of 0
|
||||||
|
// - \u2e3a, TWO-EM DASH: Width of 3
|
||||||
|
// - \u2e3b, THREE-EM DASH: Width of 4
|
||||||
|
// - East-Asian width Fullwidth and Wide: Width of 2 (Ambiguous and Neutral
|
||||||
|
// have a width of 1)
|
||||||
|
// - Regional Indicator: Width of 2
|
||||||
|
// - Extended Pictographic: Width of 2, unless Emoji Presentation is "No".
|
||||||
|
func runeWidth(r rune, graphemeProperty int) int {
|
||||||
|
switch graphemeProperty {
|
||||||
|
case prControl, prCR, prLF, prExtend, prZWJ:
|
||||||
|
return 0
|
||||||
|
case prRegionalIndicator:
|
||||||
|
return 2
|
||||||
|
case prExtendedPictographic:
|
||||||
|
if property(emojiPresentation, r) == prEmojiPresentation {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
switch r {
|
||||||
|
case 0x2e3a:
|
||||||
|
return 3
|
||||||
|
case 0x2e3b:
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
|
||||||
|
switch propertyEastAsianWidth(r) {
|
||||||
|
case prW, prF:
|
||||||
|
return 2
|
||||||
|
case prA:
|
||||||
|
return EastAsianAmbiguousWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringWidth returns the monospace width for the given string, that is, the
|
||||||
|
// number of same-size cells to be occupied by the string.
|
||||||
|
func StringWidth(s string) (width int) {
|
||||||
|
state := -1
|
||||||
|
for len(s) > 0 {
|
||||||
|
var w int
|
||||||
|
_, s, w, state = FirstGraphemeClusterInString(s, state)
|
||||||
|
width += w
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
// FirstWord returns the first word found in the given byte slice according to
|
||||||
|
// the rules of [Unicode Standard Annex #29, Word Boundaries]. This function can
|
||||||
|
// be called continuously to extract all words from a byte slice, as illustrated
|
||||||
|
// in the example below.
|
||||||
|
//
|
||||||
|
// If you don't know the current state, for example when calling the function
|
||||||
|
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||||
|
// and rest slice returned by the previous call.
|
||||||
|
//
|
||||||
|
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||||
|
// after the last byte of the identified word. If the length of the "rest" slice
|
||||||
|
// is 0, the entire byte slice "b" has been processed. The "word" byte slice is
|
||||||
|
// the sub-slice of the input slice containing the identified word.
|
||||||
|
//
|
||||||
|
// Given an empty byte slice "b", the function returns nil values.
|
||||||
|
//
|
||||||
|
// [Unicode Standard Annex #29, Word Boundaries]: http://unicode.org/reports/tr29/#Word_Boundaries
|
||||||
|
func FirstWord(b []byte, state int) (word, rest []byte, newState int) {
|
||||||
|
// An empty byte slice returns nothing.
|
||||||
|
if len(b) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the first rune.
|
||||||
|
r, length := utf8.DecodeRune(b)
|
||||||
|
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||||
|
return b, nil, wbAny
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't know the state, determine it now.
|
||||||
|
if state < 0 {
|
||||||
|
state, _ = transitionWordBreakState(state, r, b[length:], "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition until we find a boundary.
|
||||||
|
var boundary bool
|
||||||
|
for {
|
||||||
|
r, l := utf8.DecodeRune(b[length:])
|
||||||
|
state, boundary = transitionWordBreakState(state, r, b[length+l:], "")
|
||||||
|
|
||||||
|
if boundary {
|
||||||
|
return b[:length], b[length:], state
|
||||||
|
}
|
||||||
|
|
||||||
|
length += l
|
||||||
|
if len(b) <= length {
|
||||||
|
return b, nil, wbAny
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstWordInString is like [FirstWord] but its input and outputs are strings.
|
||||||
|
func FirstWordInString(str string, state int) (word, rest string, newState int) {
|
||||||
|
// An empty byte slice returns nothing.
|
||||||
|
if len(str) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the first rune.
|
||||||
|
r, length := utf8.DecodeRuneInString(str)
|
||||||
|
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||||
|
return str, "", wbAny
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't know the state, determine it now.
|
||||||
|
if state < 0 {
|
||||||
|
state, _ = transitionWordBreakState(state, r, nil, str[length:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition until we find a boundary.
|
||||||
|
var boundary bool
|
||||||
|
for {
|
||||||
|
r, l := utf8.DecodeRuneInString(str[length:])
|
||||||
|
state, boundary = transitionWordBreakState(state, r, nil, str[length+l:])
|
||||||
|
|
||||||
|
if boundary {
|
||||||
|
return str[:length], str[length:], state
|
||||||
|
}
|
||||||
|
|
||||||
|
length += l
|
||||||
|
if len(str) <= length {
|
||||||
|
return str, "", wbAny
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1883
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/wordproperties.go
generated
vendored
Normal file
1883
cli/v2/picocrypt/vendor/github.com/rivo/uniseg/wordproperties.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,282 @@
|
||||||
|
package uniseg
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
// The states of the word break parser.
|
||||||
|
const (
|
||||||
|
wbAny = iota
|
||||||
|
wbCR
|
||||||
|
wbLF
|
||||||
|
wbNewline
|
||||||
|
wbWSegSpace
|
||||||
|
wbHebrewLetter
|
||||||
|
wbALetter
|
||||||
|
wbWB7
|
||||||
|
wbWB7c
|
||||||
|
wbNumeric
|
||||||
|
wbWB11
|
||||||
|
wbKatakana
|
||||||
|
wbExtendNumLet
|
||||||
|
wbOddRI
|
||||||
|
wbEvenRI
|
||||||
|
wbZWJBit = 16 // This bit is set for any states followed by at least one zero-width joiner (see WB4 and WB3c).
|
||||||
|
)
|
||||||
|
|
||||||
|
// wbTransitions implements the word break parser's state transitions. It's
|
||||||
|
// anologous to [grTransitions], see comments there for details.
|
||||||
|
//
|
||||||
|
// Unicode version 15.0.0.
|
||||||
|
func wbTransitions(state, prop int) (newState int, wordBreak bool, rule int) {
|
||||||
|
switch uint64(state) | uint64(prop)<<32 {
|
||||||
|
// WB3b.
|
||||||
|
case wbAny | prNewline<<32:
|
||||||
|
return wbNewline, true, 32
|
||||||
|
case wbAny | prCR<<32:
|
||||||
|
return wbCR, true, 32
|
||||||
|
case wbAny | prLF<<32:
|
||||||
|
return wbLF, true, 32
|
||||||
|
|
||||||
|
// WB3a.
|
||||||
|
case wbNewline | prAny<<32:
|
||||||
|
return wbAny, true, 31
|
||||||
|
case wbCR | prAny<<32:
|
||||||
|
return wbAny, true, 31
|
||||||
|
case wbLF | prAny<<32:
|
||||||
|
return wbAny, true, 31
|
||||||
|
|
||||||
|
// WB3.
|
||||||
|
case wbCR | prLF<<32:
|
||||||
|
return wbLF, false, 30
|
||||||
|
|
||||||
|
// WB3d.
|
||||||
|
case wbAny | prWSegSpace<<32:
|
||||||
|
return wbWSegSpace, true, 9990
|
||||||
|
case wbWSegSpace | prWSegSpace<<32:
|
||||||
|
return wbWSegSpace, false, 34
|
||||||
|
|
||||||
|
// WB5.
|
||||||
|
case wbAny | prALetter<<32:
|
||||||
|
return wbALetter, true, 9990
|
||||||
|
case wbAny | prHebrewLetter<<32:
|
||||||
|
return wbHebrewLetter, true, 9990
|
||||||
|
case wbALetter | prALetter<<32:
|
||||||
|
return wbALetter, false, 50
|
||||||
|
case wbALetter | prHebrewLetter<<32:
|
||||||
|
return wbHebrewLetter, false, 50
|
||||||
|
case wbHebrewLetter | prALetter<<32:
|
||||||
|
return wbALetter, false, 50
|
||||||
|
case wbHebrewLetter | prHebrewLetter<<32:
|
||||||
|
return wbHebrewLetter, false, 50
|
||||||
|
|
||||||
|
// WB7. Transitions to wbWB7 handled by transitionWordBreakState().
|
||||||
|
case wbWB7 | prALetter<<32:
|
||||||
|
return wbALetter, false, 70
|
||||||
|
case wbWB7 | prHebrewLetter<<32:
|
||||||
|
return wbHebrewLetter, false, 70
|
||||||
|
|
||||||
|
// WB7a.
|
||||||
|
case wbHebrewLetter | prSingleQuote<<32:
|
||||||
|
return wbAny, false, 71
|
||||||
|
|
||||||
|
// WB7c. Transitions to wbWB7c handled by transitionWordBreakState().
|
||||||
|
case wbWB7c | prHebrewLetter<<32:
|
||||||
|
return wbHebrewLetter, false, 73
|
||||||
|
|
||||||
|
// WB8.
|
||||||
|
case wbAny | prNumeric<<32:
|
||||||
|
return wbNumeric, true, 9990
|
||||||
|
case wbNumeric | prNumeric<<32:
|
||||||
|
return wbNumeric, false, 80
|
||||||
|
|
||||||
|
// WB9.
|
||||||
|
case wbALetter | prNumeric<<32:
|
||||||
|
return wbNumeric, false, 90
|
||||||
|
case wbHebrewLetter | prNumeric<<32:
|
||||||
|
return wbNumeric, false, 90
|
||||||
|
|
||||||
|
// WB10.
|
||||||
|
case wbNumeric | prALetter<<32:
|
||||||
|
return wbALetter, false, 100
|
||||||
|
case wbNumeric | prHebrewLetter<<32:
|
||||||
|
return wbHebrewLetter, false, 100
|
||||||
|
|
||||||
|
// WB11. Transitions to wbWB11 handled by transitionWordBreakState().
|
||||||
|
case wbWB11 | prNumeric<<32:
|
||||||
|
return wbNumeric, false, 110
|
||||||
|
|
||||||
|
// WB13.
|
||||||
|
case wbAny | prKatakana<<32:
|
||||||
|
return wbKatakana, true, 9990
|
||||||
|
case wbKatakana | prKatakana<<32:
|
||||||
|
return wbKatakana, false, 130
|
||||||
|
|
||||||
|
// WB13a.
|
||||||
|
case wbAny | prExtendNumLet<<32:
|
||||||
|
return wbExtendNumLet, true, 9990
|
||||||
|
case wbALetter | prExtendNumLet<<32:
|
||||||
|
return wbExtendNumLet, false, 131
|
||||||
|
case wbHebrewLetter | prExtendNumLet<<32:
|
||||||
|
return wbExtendNumLet, false, 131
|
||||||
|
case wbNumeric | prExtendNumLet<<32:
|
||||||
|
return wbExtendNumLet, false, 131
|
||||||
|
case wbKatakana | prExtendNumLet<<32:
|
||||||
|
return wbExtendNumLet, false, 131
|
||||||
|
case wbExtendNumLet | prExtendNumLet<<32:
|
||||||
|
return wbExtendNumLet, false, 131
|
||||||
|
|
||||||
|
// WB13b.
|
||||||
|
case wbExtendNumLet | prALetter<<32:
|
||||||
|
return wbALetter, false, 132
|
||||||
|
case wbExtendNumLet | prHebrewLetter<<32:
|
||||||
|
return wbHebrewLetter, false, 132
|
||||||
|
case wbExtendNumLet | prNumeric<<32:
|
||||||
|
return wbNumeric, false, 132
|
||||||
|
case wbExtendNumLet | prKatakana<<32:
|
||||||
|
return wbKatakana, false, 132
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1, false, -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// transitionWordBreakState determines the new state of the word break parser
|
||||||
|
// given the current state and the next code point. It also returns whether a
|
||||||
|
// word boundary was detected. If more than one code point is needed to
|
||||||
|
// determine the new state, the byte slice or the string starting after rune "r"
|
||||||
|
// can be used (whichever is not nil or empty) for further lookups.
|
||||||
|
func transitionWordBreakState(state int, r rune, b []byte, str string) (newState int, wordBreak bool) {
|
||||||
|
// Determine the property of the next character.
|
||||||
|
nextProperty := property(workBreakCodePoints, r)
|
||||||
|
|
||||||
|
// "Replacing Ignore Rules".
|
||||||
|
if nextProperty == prZWJ {
|
||||||
|
// WB4 (for zero-width joiners).
|
||||||
|
if state == wbNewline || state == wbCR || state == wbLF {
|
||||||
|
return wbAny | wbZWJBit, true // Make sure we don't apply WB4 to WB3a.
|
||||||
|
}
|
||||||
|
if state < 0 {
|
||||||
|
return wbAny | wbZWJBit, false
|
||||||
|
}
|
||||||
|
return state | wbZWJBit, false
|
||||||
|
} else if nextProperty == prExtend || nextProperty == prFormat {
|
||||||
|
// WB4 (for Extend and Format).
|
||||||
|
if state == wbNewline || state == wbCR || state == wbLF {
|
||||||
|
return wbAny, true // Make sure we don't apply WB4 to WB3a.
|
||||||
|
}
|
||||||
|
if state == wbWSegSpace || state == wbAny|wbZWJBit {
|
||||||
|
return wbAny, false // We don't break but this is also not WB3d or WB3c.
|
||||||
|
}
|
||||||
|
if state < 0 {
|
||||||
|
return wbAny, false
|
||||||
|
}
|
||||||
|
return state, false
|
||||||
|
} else if nextProperty == prExtendedPictographic && state >= 0 && state&wbZWJBit != 0 {
|
||||||
|
// WB3c.
|
||||||
|
return wbAny, false
|
||||||
|
}
|
||||||
|
if state >= 0 {
|
||||||
|
state = state &^ wbZWJBit
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the applicable transition in the table.
|
||||||
|
var rule int
|
||||||
|
newState, wordBreak, rule = wbTransitions(state, nextProperty)
|
||||||
|
if newState < 0 {
|
||||||
|
// No specific transition found. Try the less specific ones.
|
||||||
|
anyPropState, anyPropWordBreak, anyPropRule := wbTransitions(state, prAny)
|
||||||
|
anyStateState, anyStateWordBreak, anyStateRule := wbTransitions(wbAny, nextProperty)
|
||||||
|
if anyPropState >= 0 && anyStateState >= 0 {
|
||||||
|
// Both apply. We'll use a mix (see comments for grTransitions).
|
||||||
|
newState, wordBreak, rule = anyStateState, anyStateWordBreak, anyStateRule
|
||||||
|
if anyPropRule < anyStateRule {
|
||||||
|
wordBreak, rule = anyPropWordBreak, anyPropRule
|
||||||
|
}
|
||||||
|
} else if anyPropState >= 0 {
|
||||||
|
// We only have a specific state.
|
||||||
|
newState, wordBreak, rule = anyPropState, anyPropWordBreak, anyPropRule
|
||||||
|
// This branch will probably never be reached because okAnyState will
|
||||||
|
// always be true given the current transition map. But we keep it here
|
||||||
|
// for future modifications to the transition map where this may not be
|
||||||
|
// true anymore.
|
||||||
|
} else if anyStateState >= 0 {
|
||||||
|
// We only have a specific property.
|
||||||
|
newState, wordBreak, rule = anyStateState, anyStateWordBreak, anyStateRule
|
||||||
|
} else {
|
||||||
|
// No known transition. WB999: Any ÷ Any.
|
||||||
|
newState, wordBreak, rule = wbAny, true, 9990
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For those rules that need to look up runes further in the string, we
|
||||||
|
// determine the property after nextProperty, skipping over Format, Extend,
|
||||||
|
// and ZWJ (according to WB4). It's -1 if not needed, if such a rune cannot
|
||||||
|
// be determined (because the text ends or the rune is faulty).
|
||||||
|
farProperty := -1
|
||||||
|
if rule > 60 &&
|
||||||
|
(state == wbALetter || state == wbHebrewLetter || state == wbNumeric) &&
|
||||||
|
(nextProperty == prMidLetter || nextProperty == prMidNumLet || nextProperty == prSingleQuote || // WB6.
|
||||||
|
nextProperty == prDoubleQuote || // WB7b.
|
||||||
|
nextProperty == prMidNum) { // WB12.
|
||||||
|
for {
|
||||||
|
var (
|
||||||
|
r rune
|
||||||
|
length int
|
||||||
|
)
|
||||||
|
if b != nil { // Byte slice version.
|
||||||
|
r, length = utf8.DecodeRune(b)
|
||||||
|
b = b[length:]
|
||||||
|
} else { // String version.
|
||||||
|
r, length = utf8.DecodeRuneInString(str)
|
||||||
|
str = str[length:]
|
||||||
|
}
|
||||||
|
if r == utf8.RuneError {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
prop := property(workBreakCodePoints, r)
|
||||||
|
if prop == prExtend || prop == prFormat || prop == prZWJ {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
farProperty = prop
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WB6.
|
||||||
|
if rule > 60 &&
|
||||||
|
(state == wbALetter || state == wbHebrewLetter) &&
|
||||||
|
(nextProperty == prMidLetter || nextProperty == prMidNumLet || nextProperty == prSingleQuote) &&
|
||||||
|
(farProperty == prALetter || farProperty == prHebrewLetter) {
|
||||||
|
return wbWB7, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// WB7b.
|
||||||
|
if rule > 72 &&
|
||||||
|
state == wbHebrewLetter &&
|
||||||
|
nextProperty == prDoubleQuote &&
|
||||||
|
farProperty == prHebrewLetter {
|
||||||
|
return wbWB7c, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// WB12.
|
||||||
|
if rule > 120 &&
|
||||||
|
state == wbNumeric &&
|
||||||
|
(nextProperty == prMidNum || nextProperty == prMidNumLet || nextProperty == prSingleQuote) &&
|
||||||
|
farProperty == prNumeric {
|
||||||
|
return wbWB11, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// WB15 and WB16.
|
||||||
|
if newState == wbAny && nextProperty == prRegionalIndicator {
|
||||||
|
if state != wbOddRI && state != wbEvenRI { // Includes state == -1.
|
||||||
|
// Transition into the first RI.
|
||||||
|
return wbOddRI, true
|
||||||
|
}
|
||||||
|
if state == wbOddRI {
|
||||||
|
// Don't break pairs of Regional Indicators.
|
||||||
|
return wbEvenRI, false
|
||||||
|
}
|
||||||
|
return wbOddRI, true // We can break after a pair.
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
18
cli/v2/picocrypt/vendor/github.com/schollz/progressbar/v3/.gitignore
generated
vendored
Normal file
18
cli/v2/picocrypt/vendor/github.com/schollz/progressbar/v3/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Dependency directories (remove the comment below to include it)
|
||||||
|
# vendor/
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
*.tar.gz
|
6
cli/v2/picocrypt/vendor/github.com/schollz/progressbar/v3/.travis.yml
generated
vendored
Normal file
6
cli/v2/picocrypt/vendor/github.com/schollz/progressbar/v3/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- tip
|
||||||
|
|
||||||
|
script: go test -v .
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2017 Zack
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
121
cli/v2/picocrypt/vendor/github.com/schollz/progressbar/v3/README.md
generated
vendored
Normal file
121
cli/v2/picocrypt/vendor/github.com/schollz/progressbar/v3/README.md
generated
vendored
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
# progressbar
|
||||||
|
|
||||||
|
[![CI](https://github.com/schollz/progressbar/actions/workflows/ci.yml/badge.svg?branch=main&event=push)](https://github.com/schollz/progressbar/actions/workflows/ci.yml)
|
||||||
|
[![go report card](https://goreportcard.com/badge/github.com/schollz/progressbar)](https://goreportcard.com/report/github.com/schollz/progressbar)
|
||||||
|
[![coverage](https://img.shields.io/badge/coverage-84%25-brightgreen.svg)](https://gocover.io/github.com/schollz/progressbar)
|
||||||
|
[![godocs](https://godoc.org/github.com/schollz/progressbar?status.svg)](https://godoc.org/github.com/schollz/progressbar/v3)
|
||||||
|
|
||||||
|
A very simple thread-safe progress bar which should work on every OS without problems. I needed a progressbar for [croc](https://github.com/schollz/croc) and everything I tried had problems, so I made another one. In order to be OS agnostic I do not plan to support [multi-line outputs](https://github.com/schollz/progressbar/issues/6).
|
||||||
|
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```
|
||||||
|
go get -u github.com/schollz/progressbar/v3
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic usage
|
||||||
|
|
||||||
|
```golang
|
||||||
|
bar := progressbar.Default(100)
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
bar.Add(1)
|
||||||
|
time.Sleep(40 * time.Millisecond)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
which looks like:
|
||||||
|
|
||||||
|
![Example of basic bar](examples/basic/basic.gif)
|
||||||
|
|
||||||
|
|
||||||
|
### I/O operations
|
||||||
|
|
||||||
|
The `progressbar` implements an `io.Writer` so it can automatically detect the number of bytes written to a stream, so you can use it as a progressbar for an `io.Reader`.
|
||||||
|
|
||||||
|
```golang
|
||||||
|
req, _ := http.NewRequest("GET", "https://dl.google.com/go/go1.14.2.src.tar.gz", nil)
|
||||||
|
resp, _ := http.DefaultClient.Do(req)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
f, _ := os.OpenFile("go1.14.2.src.tar.gz", os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
bar := progressbar.DefaultBytes(
|
||||||
|
resp.ContentLength,
|
||||||
|
"downloading",
|
||||||
|
)
|
||||||
|
io.Copy(io.MultiWriter(f, bar), resp.Body)
|
||||||
|
```
|
||||||
|
|
||||||
|
which looks like:
|
||||||
|
|
||||||
|
![Example of download bar](examples/download/download.gif)
|
||||||
|
|
||||||
|
|
||||||
|
### Progress bar with unknown length
|
||||||
|
|
||||||
|
A progressbar with unknown length is a spinner. Any bar with -1 length will automatically convert it to a spinner with a customizable spinner type. For example, the above code can be run and set the `resp.ContentLength` to `-1`.
|
||||||
|
|
||||||
|
which looks like:
|
||||||
|
|
||||||
|
![Example of download bar with unknown length](examples/download-unknown/download-unknown.gif)
|
||||||
|
|
||||||
|
|
||||||
|
### Customization
|
||||||
|
|
||||||
|
There is a lot of customization that you can do - change the writer, the color, the width, description, theme, etc. See [all the options](https://pkg.go.dev/github.com/schollz/progressbar/v3?tab=doc#Option).
|
||||||
|
|
||||||
|
```golang
|
||||||
|
bar := progressbar.NewOptions(1000,
|
||||||
|
progressbar.OptionSetWriter(ansi.NewAnsiStdout()), //you should install "github.com/k0kubun/go-ansi"
|
||||||
|
progressbar.OptionEnableColorCodes(true),
|
||||||
|
progressbar.OptionShowBytes(true),
|
||||||
|
progressbar.OptionSetWidth(15),
|
||||||
|
progressbar.OptionSetDescription("[cyan][1/3][reset] Writing moshable file..."),
|
||||||
|
progressbar.OptionSetTheme(progressbar.Theme{
|
||||||
|
Saucer: "[green]=[reset]",
|
||||||
|
SaucerHead: "[green]>[reset]",
|
||||||
|
SaucerPadding: " ",
|
||||||
|
BarStart: "[",
|
||||||
|
BarEnd: "]",
|
||||||
|
}))
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
bar.Add(1)
|
||||||
|
time.Sleep(5 * time.Millisecond)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
which looks like:
|
||||||
|
|
||||||
|
![Example of customized bar](examples/customization/customization.gif)
|
||||||
|
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Pull requests are welcome. Feel free to...
|
||||||
|
|
||||||
|
- Revise documentation
|
||||||
|
- Add new features
|
||||||
|
- Fix bugs
|
||||||
|
- Suggest improvements
|
||||||
|
|
||||||
|
## Thanks
|
||||||
|
|
||||||
|
Thanks [@Dynom](https://github.com/dynom) for massive improvements in version 2.0!
|
||||||
|
|
||||||
|
Thanks [@CrushedPixel](https://github.com/CrushedPixel) for adding descriptions and color code support!
|
||||||
|
|
||||||
|
Thanks [@MrMe42](https://github.com/MrMe42) for adding some minor features!
|
||||||
|
|
||||||
|
Thanks [@tehstun](https://github.com/tehstun) for some great PRs!
|
||||||
|
|
||||||
|
Thanks [@Benzammour](https://github.com/Benzammour) and [@haseth](https://github.com/haseth) for helping create v3!
|
||||||
|
|
||||||
|
Thanks [@briandowns](https://github.com/briandowns) for compiling the list of spinners.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
1132
cli/v2/picocrypt/vendor/github.com/schollz/progressbar/v3/progressbar.go
generated
vendored
Normal file
1132
cli/v2/picocrypt/vendor/github.com/schollz/progressbar/v3/progressbar.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
80
cli/v2/picocrypt/vendor/github.com/schollz/progressbar/v3/spinners.go
generated
vendored
Normal file
80
cli/v2/picocrypt/vendor/github.com/schollz/progressbar/v3/spinners.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
package progressbar
|
||||||
|
|
||||||
|
var spinners = map[int][]string{
|
||||||
|
0: {"←", "↖", "↑", "↗", "→", "↘", "↓", "↙"},
|
||||||
|
1: {"▁", "▃", "▄", "▅", "▆", "▇", "█", "▇", "▆", "▅", "▄", "▃", "▁"},
|
||||||
|
2: {"▖", "▘", "▝", "▗"},
|
||||||
|
3: {"┤", "┘", "┴", "└", "├", "┌", "┬", "┐"},
|
||||||
|
4: {"◢", "◣", "◤", "◥"},
|
||||||
|
5: {"◰", "◳", "◲", "◱"},
|
||||||
|
6: {"◴", "◷", "◶", "◵"},
|
||||||
|
7: {"◐", "◓", "◑", "◒"},
|
||||||
|
8: {".", "o", "O", "@", "*"},
|
||||||
|
9: {"|", "/", "-", "\\"},
|
||||||
|
10: {"◡◡", "⊙⊙", "◠◠"},
|
||||||
|
11: {"⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"},
|
||||||
|
12: {">))'>", " >))'>", " >))'>", " >))'>", " >))'>", " <'((<", " <'((<", " <'((<"},
|
||||||
|
13: {"⠁", "⠂", "⠄", "⡀", "⢀", "⠠", "⠐", "⠈"},
|
||||||
|
14: {"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"},
|
||||||
|
15: {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"},
|
||||||
|
16: {"▉", "▊", "▋", "▌", "▍", "▎", "▏", "▎", "▍", "▌", "▋", "▊", "▉"},
|
||||||
|
17: {"■", "□", "▪", "▫"},
|
||||||
|
18: {"←", "↑", "→", "↓"},
|
||||||
|
19: {"╫", "╪"},
|
||||||
|
20: {"⇐", "⇖", "⇑", "⇗", "⇒", "⇘", "⇓", "⇙"},
|
||||||
|
21: {"⠁", "⠁", "⠉", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠤", "⠄", "⠄", "⠤", "⠠", "⠠", "⠤", "⠦", "⠖", "⠒", "⠐", "⠐", "⠒", "⠓", "⠋", "⠉", "⠈", "⠈"},
|
||||||
|
22: {"⠈", "⠉", "⠋", "⠓", "⠒", "⠐", "⠐", "⠒", "⠖", "⠦", "⠤", "⠠", "⠠", "⠤", "⠦", "⠖", "⠒", "⠐", "⠐", "⠒", "⠓", "⠋", "⠉", "⠈"},
|
||||||
|
23: {"⠁", "⠉", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠤", "⠄", "⠄", "⠤", "⠴", "⠲", "⠒", "⠂", "⠂", "⠒", "⠚", "⠙", "⠉", "⠁"},
|
||||||
|
24: {"⠋", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠦", "⠖", "⠒", "⠐", "⠐", "⠒", "⠓", "⠋"},
|
||||||
|
25: {"ヲ", "ァ", "ィ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ッ", "ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ン"},
|
||||||
|
26: {".", "..", "..."},
|
||||||
|
27: {"▁", "▂", "▃", "▄", "▅", "▆", "▇", "█", "▉", "▊", "▋", "▌", "▍", "▎", "▏", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█", "▇", "▆", "▅", "▄", "▃", "▂", "▁"},
|
||||||
|
28: {".", "o", "O", "°", "O", "o", "."},
|
||||||
|
29: {"+", "x"},
|
||||||
|
30: {"v", "<", "^", ">"},
|
||||||
|
31: {">>--->", " >>--->", " >>--->", " >>--->", " >>--->", " <---<<", " <---<<", " <---<<", " <---<<", "<---<<"},
|
||||||
|
32: {"|", "||", "|||", "||||", "|||||", "|||||||", "||||||||", "|||||||", "||||||", "|||||", "||||", "|||", "||", "|"},
|
||||||
|
33: {"[ ]", "[= ]", "[== ]", "[=== ]", "[==== ]", "[===== ]", "[====== ]", "[======= ]", "[======== ]", "[========= ]", "[==========]"},
|
||||||
|
34: {"(*---------)", "(-*--------)", "(--*-------)", "(---*------)", "(----*-----)", "(-----*----)", "(------*---)", "(-------*--)", "(--------*-)", "(---------*)"},
|
||||||
|
35: {"█▒▒▒▒▒▒▒▒▒", "███▒▒▒▒▒▒▒", "█████▒▒▒▒▒", "███████▒▒▒", "██████████"},
|
||||||
|
36: {"[ ]", "[=> ]", "[===> ]", "[=====> ]", "[======> ]", "[========> ]", "[==========> ]", "[============> ]", "[==============> ]", "[================> ]", "[==================> ]", "[===================>]"},
|
||||||
|
37: {"ဝ", "၀"},
|
||||||
|
38: {"▌", "▀", "▐▄"},
|
||||||
|
39: {"🌍", "🌎", "🌏"},
|
||||||
|
40: {"◜", "◝", "◞", "◟"},
|
||||||
|
41: {"⬒", "⬔", "⬓", "⬕"},
|
||||||
|
42: {"⬖", "⬘", "⬗", "⬙"},
|
||||||
|
43: {"[>>> >]", "[]>>>> []", "[] >>>> []", "[] >>>> []", "[] >>>> []", "[] >>>>[]", "[>> >>]"},
|
||||||
|
44: {"♠", "♣", "♥", "♦"},
|
||||||
|
45: {"➞", "➟", "➠", "➡", "➠", "➟"},
|
||||||
|
46: {" | ", ` \ `, "_ ", ` \ `, " | ", " / ", " _", " / "},
|
||||||
|
47: {" . . . .", ". . . .", ". . . .", ". . . .", ". . . . ", ". . . . ."},
|
||||||
|
48: {" | ", " / ", " _ ", ` \ `, " | ", ` \ `, " _ ", " / "},
|
||||||
|
49: {"⎺", "⎻", "⎼", "⎽", "⎼", "⎻"},
|
||||||
|
50: {"▹▹▹▹▹", "▸▹▹▹▹", "▹▸▹▹▹", "▹▹▸▹▹", "▹▹▹▸▹", "▹▹▹▹▸"},
|
||||||
|
51: {"[ ]", "[ =]", "[ ==]", "[ ===]", "[====]", "[=== ]", "[== ]", "[= ]"},
|
||||||
|
52: {"( ● )", "( ● )", "( ● )", "( ● )", "( ●)", "( ● )", "( ● )", "( ● )", "( ● )"},
|
||||||
|
53: {"✶", "✸", "✹", "✺", "✹", "✷"},
|
||||||
|
54: {"▐|\\____________▌", "▐_|\\___________▌", "▐__|\\__________▌", "▐___|\\_________▌", "▐____|\\________▌", "▐_____|\\_______▌", "▐______|\\______▌", "▐_______|\\_____▌", "▐________|\\____▌", "▐_________|\\___▌", "▐__________|\\__▌", "▐___________|\\_▌", "▐____________|\\▌", "▐____________/|▌", "▐___________/|_▌", "▐__________/|__▌", "▐_________/|___▌", "▐________/|____▌", "▐_______/|_____▌", "▐______/|______▌", "▐_____/|_______▌", "▐____/|________▌", "▐___/|_________▌", "▐__/|__________▌", "▐_/|___________▌", "▐/|____________▌"},
|
||||||
|
55: {"▐⠂ ▌", "▐⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂▌", "▐ ⠠▌", "▐ ⡀▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐⠠ ▌"},
|
||||||
|
56: {"¿", "?"},
|
||||||
|
57: {"⢹", "⢺", "⢼", "⣸", "⣇", "⡧", "⡗", "⡏"},
|
||||||
|
58: {"⢄", "⢂", "⢁", "⡁", "⡈", "⡐", "⡠"},
|
||||||
|
59: {". ", ".. ", "...", " ..", " .", " "},
|
||||||
|
60: {".", "o", "O", "°", "O", "o", "."},
|
||||||
|
61: {"▓", "▒", "░"},
|
||||||
|
62: {"▌", "▀", "▐", "▄"},
|
||||||
|
63: {"⊶", "⊷"},
|
||||||
|
64: {"▪", "▫"},
|
||||||
|
65: {"□", "■"},
|
||||||
|
66: {"▮", "▯"},
|
||||||
|
67: {"-", "=", "≡"},
|
||||||
|
68: {"d", "q", "p", "b"},
|
||||||
|
69: {"∙∙∙", "●∙∙", "∙●∙", "∙∙●", "∙∙∙"},
|
||||||
|
70: {"🌑 ", "🌒 ", "🌓 ", "🌔 ", "🌕 ", "🌖 ", "🌗 ", "🌘 "},
|
||||||
|
71: {"☗", "☖"},
|
||||||
|
72: {"⧇", "⧆"},
|
||||||
|
73: {"◉", "◎"},
|
||||||
|
74: {"㊂", "㊀", "㊁"},
|
||||||
|
75: {"⦾", "⦿"},
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,22 @@
|
||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Go project.
|
||||||
|
|
||||||
|
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||||
|
patent license to make, have made, use, offer to sell, sell, import,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Go, where such license applies only to those patent
|
||||||
|
claims, both currently owned or controlled by Google and acquired in
|
||||||
|
the future, licensable by Google that are necessarily infringed by this
|
||||||
|
implementation of Go. This grant does not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of this
|
||||||
|
implementation. If you or your agent or exclusive licensee institute or
|
||||||
|
order or agree to the institution of patent litigation against any
|
||||||
|
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that this implementation of Go or any code incorporated within this
|
||||||
|
implementation of Go constitutes direct or contributory patent
|
||||||
|
infringement, or inducement of patent infringement, then any patent
|
||||||
|
rights granted to you under this License for this implementation of Go
|
||||||
|
shall terminate as of the date such litigation is filed.
|
|
@ -0,0 +1,283 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package argon2 implements the key derivation function Argon2.
|
||||||
|
// Argon2 was selected as the winner of the Password Hashing Competition and can
|
||||||
|
// be used to derive cryptographic keys from passwords.
|
||||||
|
//
|
||||||
|
// For a detailed specification of Argon2 see [1].
|
||||||
|
//
|
||||||
|
// If you aren't sure which function you need, use Argon2id (IDKey) and
|
||||||
|
// the parameter recommendations for your scenario.
|
||||||
|
//
|
||||||
|
// # Argon2i
|
||||||
|
//
|
||||||
|
// Argon2i (implemented by Key) is the side-channel resistant version of Argon2.
|
||||||
|
// It uses data-independent memory access, which is preferred for password
|
||||||
|
// hashing and password-based key derivation. Argon2i requires more passes over
|
||||||
|
// memory than Argon2id to protect from trade-off attacks. The recommended
|
||||||
|
// parameters (taken from [2]) for non-interactive operations are time=3 and to
|
||||||
|
// use the maximum available memory.
|
||||||
|
//
|
||||||
|
// # Argon2id
|
||||||
|
//
|
||||||
|
// Argon2id (implemented by IDKey) is a hybrid version of Argon2 combining
|
||||||
|
// Argon2i and Argon2d. It uses data-independent memory access for the first
|
||||||
|
// half of the first iteration over the memory and data-dependent memory access
|
||||||
|
// for the rest. Argon2id is side-channel resistant and provides better brute-
|
||||||
|
// force cost savings due to time-memory tradeoffs than Argon2i. The recommended
|
||||||
|
// parameters for non-interactive operations (taken from [2]) are time=1 and to
|
||||||
|
// use the maximum available memory.
|
||||||
|
//
|
||||||
|
// [1] https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf
|
||||||
|
// [2] https://tools.ietf.org/html/draft-irtf-cfrg-argon2-03#section-9.3
|
||||||
|
package argon2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/blake2b"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The Argon2 version implemented by this package.
|
||||||
|
const Version = 0x13
|
||||||
|
|
||||||
|
const (
|
||||||
|
argon2d = iota
|
||||||
|
argon2i
|
||||||
|
argon2id
|
||||||
|
)
|
||||||
|
|
||||||
|
// Key derives a key from the password, salt, and cost parameters using Argon2i
|
||||||
|
// returning a byte slice of length keyLen that can be used as cryptographic
|
||||||
|
// key. The CPU cost and parallelism degree must be greater than zero.
|
||||||
|
//
|
||||||
|
// For example, you can get a derived key for e.g. AES-256 (which needs a
|
||||||
|
// 32-byte key) by doing:
|
||||||
|
//
|
||||||
|
// key := argon2.Key([]byte("some password"), salt, 3, 32*1024, 4, 32)
|
||||||
|
//
|
||||||
|
// The draft RFC recommends[2] time=3, and memory=32*1024 is a sensible number.
|
||||||
|
// If using that amount of memory (32 MB) is not possible in some contexts then
|
||||||
|
// the time parameter can be increased to compensate.
|
||||||
|
//
|
||||||
|
// The time parameter specifies the number of passes over the memory and the
|
||||||
|
// memory parameter specifies the size of the memory in KiB. For example
|
||||||
|
// memory=32*1024 sets the memory cost to ~32 MB. The number of threads can be
|
||||||
|
// adjusted to the number of available CPUs. The cost parameters should be
|
||||||
|
// increased as memory latency and CPU parallelism increases. Remember to get a
|
||||||
|
// good random salt.
|
||||||
|
func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte {
|
||||||
|
return deriveKey(argon2i, password, salt, nil, nil, time, memory, threads, keyLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDKey derives a key from the password, salt, and cost parameters using
|
||||||
|
// Argon2id returning a byte slice of length keyLen that can be used as
|
||||||
|
// cryptographic key. The CPU cost and parallelism degree must be greater than
|
||||||
|
// zero.
|
||||||
|
//
|
||||||
|
// For example, you can get a derived key for e.g. AES-256 (which needs a
|
||||||
|
// 32-byte key) by doing:
|
||||||
|
//
|
||||||
|
// key := argon2.IDKey([]byte("some password"), salt, 1, 64*1024, 4, 32)
|
||||||
|
//
|
||||||
|
// The draft RFC recommends[2] time=1, and memory=64*1024 is a sensible number.
|
||||||
|
// If using that amount of memory (64 MB) is not possible in some contexts then
|
||||||
|
// the time parameter can be increased to compensate.
|
||||||
|
//
|
||||||
|
// The time parameter specifies the number of passes over the memory and the
|
||||||
|
// memory parameter specifies the size of the memory in KiB. For example
|
||||||
|
// memory=64*1024 sets the memory cost to ~64 MB. The number of threads can be
|
||||||
|
// adjusted to the numbers of available CPUs. The cost parameters should be
|
||||||
|
// increased as memory latency and CPU parallelism increases. Remember to get a
|
||||||
|
// good random salt.
|
||||||
|
func IDKey(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte {
|
||||||
|
return deriveKey(argon2id, password, salt, nil, nil, time, memory, threads, keyLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deriveKey(mode int, password, salt, secret, data []byte, time, memory uint32, threads uint8, keyLen uint32) []byte {
|
||||||
|
if time < 1 {
|
||||||
|
panic("argon2: number of rounds too small")
|
||||||
|
}
|
||||||
|
if threads < 1 {
|
||||||
|
panic("argon2: parallelism degree too low")
|
||||||
|
}
|
||||||
|
h0 := initHash(password, salt, secret, data, time, memory, uint32(threads), keyLen, mode)
|
||||||
|
|
||||||
|
memory = memory / (syncPoints * uint32(threads)) * (syncPoints * uint32(threads))
|
||||||
|
if memory < 2*syncPoints*uint32(threads) {
|
||||||
|
memory = 2 * syncPoints * uint32(threads)
|
||||||
|
}
|
||||||
|
B := initBlocks(&h0, memory, uint32(threads))
|
||||||
|
processBlocks(B, time, memory, uint32(threads), mode)
|
||||||
|
return extractKey(B, memory, uint32(threads), keyLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
blockLength = 128
|
||||||
|
syncPoints = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
type block [blockLength]uint64
|
||||||
|
|
||||||
|
func initHash(password, salt, key, data []byte, time, memory, threads, keyLen uint32, mode int) [blake2b.Size + 8]byte {
|
||||||
|
var (
|
||||||
|
h0 [blake2b.Size + 8]byte
|
||||||
|
params [24]byte
|
||||||
|
tmp [4]byte
|
||||||
|
)
|
||||||
|
|
||||||
|
b2, _ := blake2b.New512(nil)
|
||||||
|
binary.LittleEndian.PutUint32(params[0:4], threads)
|
||||||
|
binary.LittleEndian.PutUint32(params[4:8], keyLen)
|
||||||
|
binary.LittleEndian.PutUint32(params[8:12], memory)
|
||||||
|
binary.LittleEndian.PutUint32(params[12:16], time)
|
||||||
|
binary.LittleEndian.PutUint32(params[16:20], uint32(Version))
|
||||||
|
binary.LittleEndian.PutUint32(params[20:24], uint32(mode))
|
||||||
|
b2.Write(params[:])
|
||||||
|
binary.LittleEndian.PutUint32(tmp[:], uint32(len(password)))
|
||||||
|
b2.Write(tmp[:])
|
||||||
|
b2.Write(password)
|
||||||
|
binary.LittleEndian.PutUint32(tmp[:], uint32(len(salt)))
|
||||||
|
b2.Write(tmp[:])
|
||||||
|
b2.Write(salt)
|
||||||
|
binary.LittleEndian.PutUint32(tmp[:], uint32(len(key)))
|
||||||
|
b2.Write(tmp[:])
|
||||||
|
b2.Write(key)
|
||||||
|
binary.LittleEndian.PutUint32(tmp[:], uint32(len(data)))
|
||||||
|
b2.Write(tmp[:])
|
||||||
|
b2.Write(data)
|
||||||
|
b2.Sum(h0[:0])
|
||||||
|
return h0
|
||||||
|
}
|
||||||
|
|
||||||
|
func initBlocks(h0 *[blake2b.Size + 8]byte, memory, threads uint32) []block {
|
||||||
|
var block0 [1024]byte
|
||||||
|
B := make([]block, memory)
|
||||||
|
for lane := uint32(0); lane < threads; lane++ {
|
||||||
|
j := lane * (memory / threads)
|
||||||
|
binary.LittleEndian.PutUint32(h0[blake2b.Size+4:], lane)
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint32(h0[blake2b.Size:], 0)
|
||||||
|
blake2bHash(block0[:], h0[:])
|
||||||
|
for i := range B[j+0] {
|
||||||
|
B[j+0][i] = binary.LittleEndian.Uint64(block0[i*8:])
|
||||||
|
}
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint32(h0[blake2b.Size:], 1)
|
||||||
|
blake2bHash(block0[:], h0[:])
|
||||||
|
for i := range B[j+1] {
|
||||||
|
B[j+1][i] = binary.LittleEndian.Uint64(block0[i*8:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B
|
||||||
|
}
|
||||||
|
|
||||||
|
func processBlocks(B []block, time, memory, threads uint32, mode int) {
|
||||||
|
lanes := memory / threads
|
||||||
|
segments := lanes / syncPoints
|
||||||
|
|
||||||
|
processSegment := func(n, slice, lane uint32, wg *sync.WaitGroup) {
|
||||||
|
var addresses, in, zero block
|
||||||
|
if mode == argon2i || (mode == argon2id && n == 0 && slice < syncPoints/2) {
|
||||||
|
in[0] = uint64(n)
|
||||||
|
in[1] = uint64(lane)
|
||||||
|
in[2] = uint64(slice)
|
||||||
|
in[3] = uint64(memory)
|
||||||
|
in[4] = uint64(time)
|
||||||
|
in[5] = uint64(mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
index := uint32(0)
|
||||||
|
if n == 0 && slice == 0 {
|
||||||
|
index = 2 // we have already generated the first two blocks
|
||||||
|
if mode == argon2i || mode == argon2id {
|
||||||
|
in[6]++
|
||||||
|
processBlock(&addresses, &in, &zero)
|
||||||
|
processBlock(&addresses, &addresses, &zero)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := lane*lanes + slice*segments + index
|
||||||
|
var random uint64
|
||||||
|
for index < segments {
|
||||||
|
prev := offset - 1
|
||||||
|
if index == 0 && slice == 0 {
|
||||||
|
prev += lanes // last block in lane
|
||||||
|
}
|
||||||
|
if mode == argon2i || (mode == argon2id && n == 0 && slice < syncPoints/2) {
|
||||||
|
if index%blockLength == 0 {
|
||||||
|
in[6]++
|
||||||
|
processBlock(&addresses, &in, &zero)
|
||||||
|
processBlock(&addresses, &addresses, &zero)
|
||||||
|
}
|
||||||
|
random = addresses[index%blockLength]
|
||||||
|
} else {
|
||||||
|
random = B[prev][0]
|
||||||
|
}
|
||||||
|
newOffset := indexAlpha(random, lanes, segments, threads, n, slice, lane, index)
|
||||||
|
processBlockXOR(&B[offset], &B[prev], &B[newOffset])
|
||||||
|
index, offset = index+1, offset+1
|
||||||
|
}
|
||||||
|
wg.Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
for n := uint32(0); n < time; n++ {
|
||||||
|
for slice := uint32(0); slice < syncPoints; slice++ {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for lane := uint32(0); lane < threads; lane++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go processSegment(n, slice, lane, &wg)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractKey(B []block, memory, threads, keyLen uint32) []byte {
|
||||||
|
lanes := memory / threads
|
||||||
|
for lane := uint32(0); lane < threads-1; lane++ {
|
||||||
|
for i, v := range B[(lane*lanes)+lanes-1] {
|
||||||
|
B[memory-1][i] ^= v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var block [1024]byte
|
||||||
|
for i, v := range B[memory-1] {
|
||||||
|
binary.LittleEndian.PutUint64(block[i*8:], v)
|
||||||
|
}
|
||||||
|
key := make([]byte, keyLen)
|
||||||
|
blake2bHash(key, block[:])
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
func indexAlpha(rand uint64, lanes, segments, threads, n, slice, lane, index uint32) uint32 {
|
||||||
|
refLane := uint32(rand>>32) % threads
|
||||||
|
if n == 0 && slice == 0 {
|
||||||
|
refLane = lane
|
||||||
|
}
|
||||||
|
m, s := 3*segments, ((slice+1)%syncPoints)*segments
|
||||||
|
if lane == refLane {
|
||||||
|
m += index
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
m, s = slice*segments, 0
|
||||||
|
if slice == 0 || lane == refLane {
|
||||||
|
m += index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if index == 0 || lane == refLane {
|
||||||
|
m--
|
||||||
|
}
|
||||||
|
return phi(rand, uint64(m), uint64(s), refLane, lanes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func phi(rand, m, s uint64, lane, lanes uint32) uint32 {
|
||||||
|
p := rand & 0xFFFFFFFF
|
||||||
|
p = (p * p) >> 32
|
||||||
|
p = (p * m) >> 32
|
||||||
|
return lane*lanes + uint32((s+m-(p+1))%uint64(lanes))
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package argon2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"hash"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/blake2b"
|
||||||
|
)
|
||||||
|
|
||||||
|
// blake2bHash computes an arbitrary long hash value of in
|
||||||
|
// and writes the hash to out.
|
||||||
|
func blake2bHash(out []byte, in []byte) {
|
||||||
|
var b2 hash.Hash
|
||||||
|
if n := len(out); n < blake2b.Size {
|
||||||
|
b2, _ = blake2b.New(n, nil)
|
||||||
|
} else {
|
||||||
|
b2, _ = blake2b.New512(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
var buffer [blake2b.Size]byte
|
||||||
|
binary.LittleEndian.PutUint32(buffer[:4], uint32(len(out)))
|
||||||
|
b2.Write(buffer[:4])
|
||||||
|
b2.Write(in)
|
||||||
|
|
||||||
|
if len(out) <= blake2b.Size {
|
||||||
|
b2.Sum(out[:0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
outLen := len(out)
|
||||||
|
b2.Sum(buffer[:0])
|
||||||
|
b2.Reset()
|
||||||
|
copy(out, buffer[:32])
|
||||||
|
out = out[32:]
|
||||||
|
for len(out) > blake2b.Size {
|
||||||
|
b2.Write(buffer[:])
|
||||||
|
b2.Sum(buffer[:0])
|
||||||
|
copy(out, buffer[:32])
|
||||||
|
out = out[32:]
|
||||||
|
b2.Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
if outLen%blake2b.Size > 0 { // outLen > 64
|
||||||
|
r := ((outLen + 31) / 32) - 2 // ⌈τ /32⌉-2
|
||||||
|
b2, _ = blake2b.New(outLen-32*r, nil)
|
||||||
|
}
|
||||||
|
b2.Write(buffer[:])
|
||||||
|
b2.Sum(out[:0])
|
||||||
|
}
|
60
cli/v2/picocrypt/vendor/golang.org/x/crypto/argon2/blamka_amd64.go
generated
vendored
Normal file
60
cli/v2/picocrypt/vendor/golang.org/x/crypto/argon2/blamka_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build amd64 && gc && !purego
|
||||||
|
|
||||||
|
package argon2
|
||||||
|
|
||||||
|
import "golang.org/x/sys/cpu"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
useSSE4 = cpu.X86.HasSSE41
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func mixBlocksSSE2(out, a, b, c *block)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func xorBlocksSSE2(out, a, b, c *block)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func blamkaSSE4(b *block)
|
||||||
|
|
||||||
|
func processBlockSSE(out, in1, in2 *block, xor bool) {
|
||||||
|
var t block
|
||||||
|
mixBlocksSSE2(&t, in1, in2, &t)
|
||||||
|
if useSSE4 {
|
||||||
|
blamkaSSE4(&t)
|
||||||
|
} else {
|
||||||
|
for i := 0; i < blockLength; i += 16 {
|
||||||
|
blamkaGeneric(
|
||||||
|
&t[i+0], &t[i+1], &t[i+2], &t[i+3],
|
||||||
|
&t[i+4], &t[i+5], &t[i+6], &t[i+7],
|
||||||
|
&t[i+8], &t[i+9], &t[i+10], &t[i+11],
|
||||||
|
&t[i+12], &t[i+13], &t[i+14], &t[i+15],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
for i := 0; i < blockLength/8; i += 2 {
|
||||||
|
blamkaGeneric(
|
||||||
|
&t[i], &t[i+1], &t[16+i], &t[16+i+1],
|
||||||
|
&t[32+i], &t[32+i+1], &t[48+i], &t[48+i+1],
|
||||||
|
&t[64+i], &t[64+i+1], &t[80+i], &t[80+i+1],
|
||||||
|
&t[96+i], &t[96+i+1], &t[112+i], &t[112+i+1],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if xor {
|
||||||
|
xorBlocksSSE2(out, in1, in2, &t)
|
||||||
|
} else {
|
||||||
|
mixBlocksSSE2(out, in1, in2, &t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func processBlock(out, in1, in2 *block) {
|
||||||
|
processBlockSSE(out, in1, in2, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func processBlockXOR(out, in1, in2 *block) {
|
||||||
|
processBlockSSE(out, in1, in2, true)
|
||||||
|
}
|
243
cli/v2/picocrypt/vendor/golang.org/x/crypto/argon2/blamka_amd64.s
generated
vendored
Normal file
243
cli/v2/picocrypt/vendor/golang.org/x/crypto/argon2/blamka_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build amd64 && gc && !purego
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
DATA ·c40<>+0x00(SB)/8, $0x0201000706050403
|
||||||
|
DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
|
||||||
|
GLOBL ·c40<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
DATA ·c48<>+0x00(SB)/8, $0x0100070605040302
|
||||||
|
DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
|
||||||
|
GLOBL ·c48<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \
|
||||||
|
MOVO v4, t1; \
|
||||||
|
MOVO v5, v4; \
|
||||||
|
MOVO t1, v5; \
|
||||||
|
MOVO v6, t1; \
|
||||||
|
PUNPCKLQDQ v6, t2; \
|
||||||
|
PUNPCKHQDQ v7, v6; \
|
||||||
|
PUNPCKHQDQ t2, v6; \
|
||||||
|
PUNPCKLQDQ v7, t2; \
|
||||||
|
MOVO t1, v7; \
|
||||||
|
MOVO v2, t1; \
|
||||||
|
PUNPCKHQDQ t2, v7; \
|
||||||
|
PUNPCKLQDQ v3, t2; \
|
||||||
|
PUNPCKHQDQ t2, v2; \
|
||||||
|
PUNPCKLQDQ t1, t2; \
|
||||||
|
PUNPCKHQDQ t2, v3
|
||||||
|
|
||||||
|
#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \
|
||||||
|
MOVO v4, t1; \
|
||||||
|
MOVO v5, v4; \
|
||||||
|
MOVO t1, v5; \
|
||||||
|
MOVO v2, t1; \
|
||||||
|
PUNPCKLQDQ v2, t2; \
|
||||||
|
PUNPCKHQDQ v3, v2; \
|
||||||
|
PUNPCKHQDQ t2, v2; \
|
||||||
|
PUNPCKLQDQ v3, t2; \
|
||||||
|
MOVO t1, v3; \
|
||||||
|
MOVO v6, t1; \
|
||||||
|
PUNPCKHQDQ t2, v3; \
|
||||||
|
PUNPCKLQDQ v7, t2; \
|
||||||
|
PUNPCKHQDQ t2, v6; \
|
||||||
|
PUNPCKLQDQ t1, t2; \
|
||||||
|
PUNPCKHQDQ t2, v7
|
||||||
|
|
||||||
|
#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, t0, c40, c48) \
|
||||||
|
MOVO v0, t0; \
|
||||||
|
PMULULQ v2, t0; \
|
||||||
|
PADDQ v2, v0; \
|
||||||
|
PADDQ t0, v0; \
|
||||||
|
PADDQ t0, v0; \
|
||||||
|
PXOR v0, v6; \
|
||||||
|
PSHUFD $0xB1, v6, v6; \
|
||||||
|
MOVO v4, t0; \
|
||||||
|
PMULULQ v6, t0; \
|
||||||
|
PADDQ v6, v4; \
|
||||||
|
PADDQ t0, v4; \
|
||||||
|
PADDQ t0, v4; \
|
||||||
|
PXOR v4, v2; \
|
||||||
|
PSHUFB c40, v2; \
|
||||||
|
MOVO v0, t0; \
|
||||||
|
PMULULQ v2, t0; \
|
||||||
|
PADDQ v2, v0; \
|
||||||
|
PADDQ t0, v0; \
|
||||||
|
PADDQ t0, v0; \
|
||||||
|
PXOR v0, v6; \
|
||||||
|
PSHUFB c48, v6; \
|
||||||
|
MOVO v4, t0; \
|
||||||
|
PMULULQ v6, t0; \
|
||||||
|
PADDQ v6, v4; \
|
||||||
|
PADDQ t0, v4; \
|
||||||
|
PADDQ t0, v4; \
|
||||||
|
PXOR v4, v2; \
|
||||||
|
MOVO v2, t0; \
|
||||||
|
PADDQ v2, t0; \
|
||||||
|
PSRLQ $63, v2; \
|
||||||
|
PXOR t0, v2; \
|
||||||
|
MOVO v1, t0; \
|
||||||
|
PMULULQ v3, t0; \
|
||||||
|
PADDQ v3, v1; \
|
||||||
|
PADDQ t0, v1; \
|
||||||
|
PADDQ t0, v1; \
|
||||||
|
PXOR v1, v7; \
|
||||||
|
PSHUFD $0xB1, v7, v7; \
|
||||||
|
MOVO v5, t0; \
|
||||||
|
PMULULQ v7, t0; \
|
||||||
|
PADDQ v7, v5; \
|
||||||
|
PADDQ t0, v5; \
|
||||||
|
PADDQ t0, v5; \
|
||||||
|
PXOR v5, v3; \
|
||||||
|
PSHUFB c40, v3; \
|
||||||
|
MOVO v1, t0; \
|
||||||
|
PMULULQ v3, t0; \
|
||||||
|
PADDQ v3, v1; \
|
||||||
|
PADDQ t0, v1; \
|
||||||
|
PADDQ t0, v1; \
|
||||||
|
PXOR v1, v7; \
|
||||||
|
PSHUFB c48, v7; \
|
||||||
|
MOVO v5, t0; \
|
||||||
|
PMULULQ v7, t0; \
|
||||||
|
PADDQ v7, v5; \
|
||||||
|
PADDQ t0, v5; \
|
||||||
|
PADDQ t0, v5; \
|
||||||
|
PXOR v5, v3; \
|
||||||
|
MOVO v3, t0; \
|
||||||
|
PADDQ v3, t0; \
|
||||||
|
PSRLQ $63, v3; \
|
||||||
|
PXOR t0, v3
|
||||||
|
|
||||||
|
#define LOAD_MSG_0(block, off) \
|
||||||
|
MOVOU 8*(off+0)(block), X0; \
|
||||||
|
MOVOU 8*(off+2)(block), X1; \
|
||||||
|
MOVOU 8*(off+4)(block), X2; \
|
||||||
|
MOVOU 8*(off+6)(block), X3; \
|
||||||
|
MOVOU 8*(off+8)(block), X4; \
|
||||||
|
MOVOU 8*(off+10)(block), X5; \
|
||||||
|
MOVOU 8*(off+12)(block), X6; \
|
||||||
|
MOVOU 8*(off+14)(block), X7
|
||||||
|
|
||||||
|
#define STORE_MSG_0(block, off) \
|
||||||
|
MOVOU X0, 8*(off+0)(block); \
|
||||||
|
MOVOU X1, 8*(off+2)(block); \
|
||||||
|
MOVOU X2, 8*(off+4)(block); \
|
||||||
|
MOVOU X3, 8*(off+6)(block); \
|
||||||
|
MOVOU X4, 8*(off+8)(block); \
|
||||||
|
MOVOU X5, 8*(off+10)(block); \
|
||||||
|
MOVOU X6, 8*(off+12)(block); \
|
||||||
|
MOVOU X7, 8*(off+14)(block)
|
||||||
|
|
||||||
|
#define LOAD_MSG_1(block, off) \
|
||||||
|
MOVOU 8*off+0*8(block), X0; \
|
||||||
|
MOVOU 8*off+16*8(block), X1; \
|
||||||
|
MOVOU 8*off+32*8(block), X2; \
|
||||||
|
MOVOU 8*off+48*8(block), X3; \
|
||||||
|
MOVOU 8*off+64*8(block), X4; \
|
||||||
|
MOVOU 8*off+80*8(block), X5; \
|
||||||
|
MOVOU 8*off+96*8(block), X6; \
|
||||||
|
MOVOU 8*off+112*8(block), X7
|
||||||
|
|
||||||
|
#define STORE_MSG_1(block, off) \
|
||||||
|
MOVOU X0, 8*off+0*8(block); \
|
||||||
|
MOVOU X1, 8*off+16*8(block); \
|
||||||
|
MOVOU X2, 8*off+32*8(block); \
|
||||||
|
MOVOU X3, 8*off+48*8(block); \
|
||||||
|
MOVOU X4, 8*off+64*8(block); \
|
||||||
|
MOVOU X5, 8*off+80*8(block); \
|
||||||
|
MOVOU X6, 8*off+96*8(block); \
|
||||||
|
MOVOU X7, 8*off+112*8(block)
|
||||||
|
|
||||||
|
#define BLAMKA_ROUND_0(block, off, t0, t1, c40, c48) \
|
||||||
|
LOAD_MSG_0(block, off); \
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1); \
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1); \
|
||||||
|
STORE_MSG_0(block, off)
|
||||||
|
|
||||||
|
#define BLAMKA_ROUND_1(block, off, t0, t1, c40, c48) \
|
||||||
|
LOAD_MSG_1(block, off); \
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1); \
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1); \
|
||||||
|
STORE_MSG_1(block, off)
|
||||||
|
|
||||||
|
// func blamkaSSE4(b *block)
|
||||||
|
TEXT ·blamkaSSE4(SB), 4, $0-8
|
||||||
|
MOVQ b+0(FP), AX
|
||||||
|
|
||||||
|
MOVOU ·c40<>(SB), X10
|
||||||
|
MOVOU ·c48<>(SB), X11
|
||||||
|
|
||||||
|
BLAMKA_ROUND_0(AX, 0, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_0(AX, 16, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_0(AX, 32, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_0(AX, 48, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_0(AX, 64, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_0(AX, 80, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_0(AX, 96, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_0(AX, 112, X8, X9, X10, X11)
|
||||||
|
|
||||||
|
BLAMKA_ROUND_1(AX, 0, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_1(AX, 2, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_1(AX, 4, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_1(AX, 6, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_1(AX, 8, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_1(AX, 10, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_1(AX, 12, X8, X9, X10, X11)
|
||||||
|
BLAMKA_ROUND_1(AX, 14, X8, X9, X10, X11)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func mixBlocksSSE2(out, a, b, c *block)
|
||||||
|
TEXT ·mixBlocksSSE2(SB), 4, $0-32
|
||||||
|
MOVQ out+0(FP), DX
|
||||||
|
MOVQ a+8(FP), AX
|
||||||
|
MOVQ b+16(FP), BX
|
||||||
|
MOVQ c+24(FP), CX
|
||||||
|
MOVQ $128, DI
|
||||||
|
|
||||||
|
loop:
|
||||||
|
MOVOU 0(AX), X0
|
||||||
|
MOVOU 0(BX), X1
|
||||||
|
MOVOU 0(CX), X2
|
||||||
|
PXOR X1, X0
|
||||||
|
PXOR X2, X0
|
||||||
|
MOVOU X0, 0(DX)
|
||||||
|
ADDQ $16, AX
|
||||||
|
ADDQ $16, BX
|
||||||
|
ADDQ $16, CX
|
||||||
|
ADDQ $16, DX
|
||||||
|
SUBQ $2, DI
|
||||||
|
JA loop
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func xorBlocksSSE2(out, a, b, c *block)
|
||||||
|
TEXT ·xorBlocksSSE2(SB), 4, $0-32
|
||||||
|
MOVQ out+0(FP), DX
|
||||||
|
MOVQ a+8(FP), AX
|
||||||
|
MOVQ b+16(FP), BX
|
||||||
|
MOVQ c+24(FP), CX
|
||||||
|
MOVQ $128, DI
|
||||||
|
|
||||||
|
loop:
|
||||||
|
MOVOU 0(AX), X0
|
||||||
|
MOVOU 0(BX), X1
|
||||||
|
MOVOU 0(CX), X2
|
||||||
|
MOVOU 0(DX), X3
|
||||||
|
PXOR X1, X0
|
||||||
|
PXOR X2, X0
|
||||||
|
PXOR X3, X0
|
||||||
|
MOVOU X0, 0(DX)
|
||||||
|
ADDQ $16, AX
|
||||||
|
ADDQ $16, BX
|
||||||
|
ADDQ $16, CX
|
||||||
|
ADDQ $16, DX
|
||||||
|
SUBQ $2, DI
|
||||||
|
JA loop
|
||||||
|
RET
|
163
cli/v2/picocrypt/vendor/golang.org/x/crypto/argon2/blamka_generic.go
generated
vendored
Normal file
163
cli/v2/picocrypt/vendor/golang.org/x/crypto/argon2/blamka_generic.go
generated
vendored
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package argon2
|
||||||
|
|
||||||
|
var useSSE4 bool
|
||||||
|
|
||||||
|
func processBlockGeneric(out, in1, in2 *block, xor bool) {
|
||||||
|
var t block
|
||||||
|
for i := range t {
|
||||||
|
t[i] = in1[i] ^ in2[i]
|
||||||
|
}
|
||||||
|
for i := 0; i < blockLength; i += 16 {
|
||||||
|
blamkaGeneric(
|
||||||
|
&t[i+0], &t[i+1], &t[i+2], &t[i+3],
|
||||||
|
&t[i+4], &t[i+5], &t[i+6], &t[i+7],
|
||||||
|
&t[i+8], &t[i+9], &t[i+10], &t[i+11],
|
||||||
|
&t[i+12], &t[i+13], &t[i+14], &t[i+15],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
for i := 0; i < blockLength/8; i += 2 {
|
||||||
|
blamkaGeneric(
|
||||||
|
&t[i], &t[i+1], &t[16+i], &t[16+i+1],
|
||||||
|
&t[32+i], &t[32+i+1], &t[48+i], &t[48+i+1],
|
||||||
|
&t[64+i], &t[64+i+1], &t[80+i], &t[80+i+1],
|
||||||
|
&t[96+i], &t[96+i+1], &t[112+i], &t[112+i+1],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if xor {
|
||||||
|
for i := range t {
|
||||||
|
out[i] ^= in1[i] ^ in2[i] ^ t[i]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := range t {
|
||||||
|
out[i] = in1[i] ^ in2[i] ^ t[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func blamkaGeneric(t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15 *uint64) {
|
||||||
|
v00, v01, v02, v03 := *t00, *t01, *t02, *t03
|
||||||
|
v04, v05, v06, v07 := *t04, *t05, *t06, *t07
|
||||||
|
v08, v09, v10, v11 := *t08, *t09, *t10, *t11
|
||||||
|
v12, v13, v14, v15 := *t12, *t13, *t14, *t15
|
||||||
|
|
||||||
|
v00 += v04 + 2*uint64(uint32(v00))*uint64(uint32(v04))
|
||||||
|
v12 ^= v00
|
||||||
|
v12 = v12>>32 | v12<<32
|
||||||
|
v08 += v12 + 2*uint64(uint32(v08))*uint64(uint32(v12))
|
||||||
|
v04 ^= v08
|
||||||
|
v04 = v04>>24 | v04<<40
|
||||||
|
|
||||||
|
v00 += v04 + 2*uint64(uint32(v00))*uint64(uint32(v04))
|
||||||
|
v12 ^= v00
|
||||||
|
v12 = v12>>16 | v12<<48
|
||||||
|
v08 += v12 + 2*uint64(uint32(v08))*uint64(uint32(v12))
|
||||||
|
v04 ^= v08
|
||||||
|
v04 = v04>>63 | v04<<1
|
||||||
|
|
||||||
|
v01 += v05 + 2*uint64(uint32(v01))*uint64(uint32(v05))
|
||||||
|
v13 ^= v01
|
||||||
|
v13 = v13>>32 | v13<<32
|
||||||
|
v09 += v13 + 2*uint64(uint32(v09))*uint64(uint32(v13))
|
||||||
|
v05 ^= v09
|
||||||
|
v05 = v05>>24 | v05<<40
|
||||||
|
|
||||||
|
v01 += v05 + 2*uint64(uint32(v01))*uint64(uint32(v05))
|
||||||
|
v13 ^= v01
|
||||||
|
v13 = v13>>16 | v13<<48
|
||||||
|
v09 += v13 + 2*uint64(uint32(v09))*uint64(uint32(v13))
|
||||||
|
v05 ^= v09
|
||||||
|
v05 = v05>>63 | v05<<1
|
||||||
|
|
||||||
|
v02 += v06 + 2*uint64(uint32(v02))*uint64(uint32(v06))
|
||||||
|
v14 ^= v02
|
||||||
|
v14 = v14>>32 | v14<<32
|
||||||
|
v10 += v14 + 2*uint64(uint32(v10))*uint64(uint32(v14))
|
||||||
|
v06 ^= v10
|
||||||
|
v06 = v06>>24 | v06<<40
|
||||||
|
|
||||||
|
v02 += v06 + 2*uint64(uint32(v02))*uint64(uint32(v06))
|
||||||
|
v14 ^= v02
|
||||||
|
v14 = v14>>16 | v14<<48
|
||||||
|
v10 += v14 + 2*uint64(uint32(v10))*uint64(uint32(v14))
|
||||||
|
v06 ^= v10
|
||||||
|
v06 = v06>>63 | v06<<1
|
||||||
|
|
||||||
|
v03 += v07 + 2*uint64(uint32(v03))*uint64(uint32(v07))
|
||||||
|
v15 ^= v03
|
||||||
|
v15 = v15>>32 | v15<<32
|
||||||
|
v11 += v15 + 2*uint64(uint32(v11))*uint64(uint32(v15))
|
||||||
|
v07 ^= v11
|
||||||
|
v07 = v07>>24 | v07<<40
|
||||||
|
|
||||||
|
v03 += v07 + 2*uint64(uint32(v03))*uint64(uint32(v07))
|
||||||
|
v15 ^= v03
|
||||||
|
v15 = v15>>16 | v15<<48
|
||||||
|
v11 += v15 + 2*uint64(uint32(v11))*uint64(uint32(v15))
|
||||||
|
v07 ^= v11
|
||||||
|
v07 = v07>>63 | v07<<1
|
||||||
|
|
||||||
|
v00 += v05 + 2*uint64(uint32(v00))*uint64(uint32(v05))
|
||||||
|
v15 ^= v00
|
||||||
|
v15 = v15>>32 | v15<<32
|
||||||
|
v10 += v15 + 2*uint64(uint32(v10))*uint64(uint32(v15))
|
||||||
|
v05 ^= v10
|
||||||
|
v05 = v05>>24 | v05<<40
|
||||||
|
|
||||||
|
v00 += v05 + 2*uint64(uint32(v00))*uint64(uint32(v05))
|
||||||
|
v15 ^= v00
|
||||||
|
v15 = v15>>16 | v15<<48
|
||||||
|
v10 += v15 + 2*uint64(uint32(v10))*uint64(uint32(v15))
|
||||||
|
v05 ^= v10
|
||||||
|
v05 = v05>>63 | v05<<1
|
||||||
|
|
||||||
|
v01 += v06 + 2*uint64(uint32(v01))*uint64(uint32(v06))
|
||||||
|
v12 ^= v01
|
||||||
|
v12 = v12>>32 | v12<<32
|
||||||
|
v11 += v12 + 2*uint64(uint32(v11))*uint64(uint32(v12))
|
||||||
|
v06 ^= v11
|
||||||
|
v06 = v06>>24 | v06<<40
|
||||||
|
|
||||||
|
v01 += v06 + 2*uint64(uint32(v01))*uint64(uint32(v06))
|
||||||
|
v12 ^= v01
|
||||||
|
v12 = v12>>16 | v12<<48
|
||||||
|
v11 += v12 + 2*uint64(uint32(v11))*uint64(uint32(v12))
|
||||||
|
v06 ^= v11
|
||||||
|
v06 = v06>>63 | v06<<1
|
||||||
|
|
||||||
|
v02 += v07 + 2*uint64(uint32(v02))*uint64(uint32(v07))
|
||||||
|
v13 ^= v02
|
||||||
|
v13 = v13>>32 | v13<<32
|
||||||
|
v08 += v13 + 2*uint64(uint32(v08))*uint64(uint32(v13))
|
||||||
|
v07 ^= v08
|
||||||
|
v07 = v07>>24 | v07<<40
|
||||||
|
|
||||||
|
v02 += v07 + 2*uint64(uint32(v02))*uint64(uint32(v07))
|
||||||
|
v13 ^= v02
|
||||||
|
v13 = v13>>16 | v13<<48
|
||||||
|
v08 += v13 + 2*uint64(uint32(v08))*uint64(uint32(v13))
|
||||||
|
v07 ^= v08
|
||||||
|
v07 = v07>>63 | v07<<1
|
||||||
|
|
||||||
|
v03 += v04 + 2*uint64(uint32(v03))*uint64(uint32(v04))
|
||||||
|
v14 ^= v03
|
||||||
|
v14 = v14>>32 | v14<<32
|
||||||
|
v09 += v14 + 2*uint64(uint32(v09))*uint64(uint32(v14))
|
||||||
|
v04 ^= v09
|
||||||
|
v04 = v04>>24 | v04<<40
|
||||||
|
|
||||||
|
v03 += v04 + 2*uint64(uint32(v03))*uint64(uint32(v04))
|
||||||
|
v14 ^= v03
|
||||||
|
v14 = v14>>16 | v14<<48
|
||||||
|
v09 += v14 + 2*uint64(uint32(v09))*uint64(uint32(v14))
|
||||||
|
v04 ^= v09
|
||||||
|
v04 = v04>>63 | v04<<1
|
||||||
|
|
||||||
|
*t00, *t01, *t02, *t03 = v00, v01, v02, v03
|
||||||
|
*t04, *t05, *t06, *t07 = v04, v05, v06, v07
|
||||||
|
*t08, *t09, *t10, *t11 = v08, v09, v10, v11
|
||||||
|
*t12, *t13, *t14, *t15 = v12, v13, v14, v15
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !amd64 || purego || !gc
|
||||||
|
|
||||||
|
package argon2
|
||||||
|
|
||||||
|
func processBlock(out, in1, in2 *block) {
|
||||||
|
processBlockGeneric(out, in1, in2, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func processBlockXOR(out, in1, in2 *block) {
|
||||||
|
processBlockGeneric(out, in1, in2, true)
|
||||||
|
}
|
|
@ -0,0 +1,291 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package blake2b implements the BLAKE2b hash algorithm defined by RFC 7693
|
||||||
|
// and the extendable output function (XOF) BLAKE2Xb.
|
||||||
|
//
|
||||||
|
// BLAKE2b is optimized for 64-bit platforms—including NEON-enabled ARMs—and
|
||||||
|
// produces digests of any size between 1 and 64 bytes.
|
||||||
|
// For a detailed specification of BLAKE2b see https://blake2.net/blake2.pdf
|
||||||
|
// and for BLAKE2Xb see https://blake2.net/blake2x.pdf
|
||||||
|
//
|
||||||
|
// If you aren't sure which function you need, use BLAKE2b (Sum512 or New512).
|
||||||
|
// If you need a secret-key MAC (message authentication code), use the New512
|
||||||
|
// function with a non-nil key.
|
||||||
|
//
|
||||||
|
// BLAKE2X is a construction to compute hash values larger than 64 bytes. It
|
||||||
|
// can produce hash values between 0 and 4 GiB.
|
||||||
|
package blake2b
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// The blocksize of BLAKE2b in bytes.
|
||||||
|
BlockSize = 128
|
||||||
|
// The hash size of BLAKE2b-512 in bytes.
|
||||||
|
Size = 64
|
||||||
|
// The hash size of BLAKE2b-384 in bytes.
|
||||||
|
Size384 = 48
|
||||||
|
// The hash size of BLAKE2b-256 in bytes.
|
||||||
|
Size256 = 32
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
useAVX2 bool
|
||||||
|
useAVX bool
|
||||||
|
useSSE4 bool
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errKeySize = errors.New("blake2b: invalid key size")
|
||||||
|
errHashSize = errors.New("blake2b: invalid hash size")
|
||||||
|
)
|
||||||
|
|
||||||
|
var iv = [8]uint64{
|
||||||
|
0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
|
||||||
|
0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum512 returns the BLAKE2b-512 checksum of the data.
|
||||||
|
func Sum512(data []byte) [Size]byte {
|
||||||
|
var sum [Size]byte
|
||||||
|
checkSum(&sum, Size, data)
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum384 returns the BLAKE2b-384 checksum of the data.
|
||||||
|
func Sum384(data []byte) [Size384]byte {
|
||||||
|
var sum [Size]byte
|
||||||
|
var sum384 [Size384]byte
|
||||||
|
checkSum(&sum, Size384, data)
|
||||||
|
copy(sum384[:], sum[:Size384])
|
||||||
|
return sum384
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum256 returns the BLAKE2b-256 checksum of the data.
|
||||||
|
func Sum256(data []byte) [Size256]byte {
|
||||||
|
var sum [Size]byte
|
||||||
|
var sum256 [Size256]byte
|
||||||
|
checkSum(&sum, Size256, data)
|
||||||
|
copy(sum256[:], sum[:Size256])
|
||||||
|
return sum256
|
||||||
|
}
|
||||||
|
|
||||||
|
// New512 returns a new hash.Hash computing the BLAKE2b-512 checksum. A non-nil
|
||||||
|
// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
|
||||||
|
func New512(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
|
||||||
|
|
||||||
|
// New384 returns a new hash.Hash computing the BLAKE2b-384 checksum. A non-nil
|
||||||
|
// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
|
||||||
|
func New384(key []byte) (hash.Hash, error) { return newDigest(Size384, key) }
|
||||||
|
|
||||||
|
// New256 returns a new hash.Hash computing the BLAKE2b-256 checksum. A non-nil
|
||||||
|
// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
|
||||||
|
func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) }
|
||||||
|
|
||||||
|
// New returns a new hash.Hash computing the BLAKE2b checksum with a custom length.
|
||||||
|
// A non-nil key turns the hash into a MAC. The key must be between zero and 64 bytes long.
|
||||||
|
// The hash size can be a value between 1 and 64 but it is highly recommended to use
|
||||||
|
// values equal or greater than:
|
||||||
|
// - 32 if BLAKE2b is used as a hash function (The key is zero bytes long).
|
||||||
|
// - 16 if BLAKE2b is used as a MAC function (The key is at least 16 bytes long).
|
||||||
|
// When the key is nil, the returned hash.Hash implements BinaryMarshaler
|
||||||
|
// and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash.
|
||||||
|
func New(size int, key []byte) (hash.Hash, error) { return newDigest(size, key) }
|
||||||
|
|
||||||
|
func newDigest(hashSize int, key []byte) (*digest, error) {
|
||||||
|
if hashSize < 1 || hashSize > Size {
|
||||||
|
return nil, errHashSize
|
||||||
|
}
|
||||||
|
if len(key) > Size {
|
||||||
|
return nil, errKeySize
|
||||||
|
}
|
||||||
|
d := &digest{
|
||||||
|
size: hashSize,
|
||||||
|
keyLen: len(key),
|
||||||
|
}
|
||||||
|
copy(d.key[:], key)
|
||||||
|
d.Reset()
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkSum(sum *[Size]byte, hashSize int, data []byte) {
|
||||||
|
h := iv
|
||||||
|
h[0] ^= uint64(hashSize) | (1 << 16) | (1 << 24)
|
||||||
|
var c [2]uint64
|
||||||
|
|
||||||
|
if length := len(data); length > BlockSize {
|
||||||
|
n := length &^ (BlockSize - 1)
|
||||||
|
if length == n {
|
||||||
|
n -= BlockSize
|
||||||
|
}
|
||||||
|
hashBlocks(&h, &c, 0, data[:n])
|
||||||
|
data = data[n:]
|
||||||
|
}
|
||||||
|
|
||||||
|
var block [BlockSize]byte
|
||||||
|
offset := copy(block[:], data)
|
||||||
|
remaining := uint64(BlockSize - offset)
|
||||||
|
if c[0] < remaining {
|
||||||
|
c[1]--
|
||||||
|
}
|
||||||
|
c[0] -= remaining
|
||||||
|
|
||||||
|
hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])
|
||||||
|
|
||||||
|
for i, v := range h[:(hashSize+7)/8] {
|
||||||
|
binary.LittleEndian.PutUint64(sum[8*i:], v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type digest struct {
|
||||||
|
h [8]uint64
|
||||||
|
c [2]uint64
|
||||||
|
size int
|
||||||
|
block [BlockSize]byte
|
||||||
|
offset int
|
||||||
|
|
||||||
|
key [BlockSize]byte
|
||||||
|
keyLen int
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
magic = "b2b"
|
||||||
|
marshaledSize = len(magic) + 8*8 + 2*8 + 1 + BlockSize + 1
|
||||||
|
)
|
||||||
|
|
||||||
|
func (d *digest) MarshalBinary() ([]byte, error) {
|
||||||
|
if d.keyLen != 0 {
|
||||||
|
return nil, errors.New("crypto/blake2b: cannot marshal MACs")
|
||||||
|
}
|
||||||
|
b := make([]byte, 0, marshaledSize)
|
||||||
|
b = append(b, magic...)
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
b = appendUint64(b, d.h[i])
|
||||||
|
}
|
||||||
|
b = appendUint64(b, d.c[0])
|
||||||
|
b = appendUint64(b, d.c[1])
|
||||||
|
// Maximum value for size is 64
|
||||||
|
b = append(b, byte(d.size))
|
||||||
|
b = append(b, d.block[:]...)
|
||||||
|
b = append(b, byte(d.offset))
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *digest) UnmarshalBinary(b []byte) error {
|
||||||
|
if len(b) < len(magic) || string(b[:len(magic)]) != magic {
|
||||||
|
return errors.New("crypto/blake2b: invalid hash state identifier")
|
||||||
|
}
|
||||||
|
if len(b) != marshaledSize {
|
||||||
|
return errors.New("crypto/blake2b: invalid hash state size")
|
||||||
|
}
|
||||||
|
b = b[len(magic):]
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
b, d.h[i] = consumeUint64(b)
|
||||||
|
}
|
||||||
|
b, d.c[0] = consumeUint64(b)
|
||||||
|
b, d.c[1] = consumeUint64(b)
|
||||||
|
d.size = int(b[0])
|
||||||
|
b = b[1:]
|
||||||
|
copy(d.block[:], b[:BlockSize])
|
||||||
|
b = b[BlockSize:]
|
||||||
|
d.offset = int(b[0])
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *digest) BlockSize() int { return BlockSize }
|
||||||
|
|
||||||
|
func (d *digest) Size() int { return d.size }
|
||||||
|
|
||||||
|
func (d *digest) Reset() {
|
||||||
|
d.h = iv
|
||||||
|
d.h[0] ^= uint64(d.size) | (uint64(d.keyLen) << 8) | (1 << 16) | (1 << 24)
|
||||||
|
d.offset, d.c[0], d.c[1] = 0, 0, 0
|
||||||
|
if d.keyLen > 0 {
|
||||||
|
d.block = d.key
|
||||||
|
d.offset = BlockSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *digest) Write(p []byte) (n int, err error) {
|
||||||
|
n = len(p)
|
||||||
|
|
||||||
|
if d.offset > 0 {
|
||||||
|
remaining := BlockSize - d.offset
|
||||||
|
if n <= remaining {
|
||||||
|
d.offset += copy(d.block[d.offset:], p)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
copy(d.block[d.offset:], p[:remaining])
|
||||||
|
hashBlocks(&d.h, &d.c, 0, d.block[:])
|
||||||
|
d.offset = 0
|
||||||
|
p = p[remaining:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if length := len(p); length > BlockSize {
|
||||||
|
nn := length &^ (BlockSize - 1)
|
||||||
|
if length == nn {
|
||||||
|
nn -= BlockSize
|
||||||
|
}
|
||||||
|
hashBlocks(&d.h, &d.c, 0, p[:nn])
|
||||||
|
p = p[nn:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(p) > 0 {
|
||||||
|
d.offset += copy(d.block[:], p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *digest) Sum(sum []byte) []byte {
|
||||||
|
var hash [Size]byte
|
||||||
|
d.finalize(&hash)
|
||||||
|
return append(sum, hash[:d.size]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *digest) finalize(hash *[Size]byte) {
|
||||||
|
var block [BlockSize]byte
|
||||||
|
copy(block[:], d.block[:d.offset])
|
||||||
|
remaining := uint64(BlockSize - d.offset)
|
||||||
|
|
||||||
|
c := d.c
|
||||||
|
if c[0] < remaining {
|
||||||
|
c[1]--
|
||||||
|
}
|
||||||
|
c[0] -= remaining
|
||||||
|
|
||||||
|
h := d.h
|
||||||
|
hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])
|
||||||
|
|
||||||
|
for i, v := range h {
|
||||||
|
binary.LittleEndian.PutUint64(hash[8*i:], v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendUint64(b []byte, x uint64) []byte {
|
||||||
|
var a [8]byte
|
||||||
|
binary.BigEndian.PutUint64(a[:], x)
|
||||||
|
return append(b, a[:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendUint32(b []byte, x uint32) []byte {
|
||||||
|
var a [4]byte
|
||||||
|
binary.BigEndian.PutUint32(a[:], x)
|
||||||
|
return append(b, a[:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func consumeUint64(b []byte) ([]byte, uint64) {
|
||||||
|
x := binary.BigEndian.Uint64(b)
|
||||||
|
return b[8:], x
|
||||||
|
}
|
||||||
|
|
||||||
|
func consumeUint32(b []byte) ([]byte, uint32) {
|
||||||
|
x := binary.BigEndian.Uint32(b)
|
||||||
|
return b[4:], x
|
||||||
|
}
|
37
cli/v2/picocrypt/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
generated
vendored
Normal file
37
cli/v2/picocrypt/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build amd64 && gc && !purego
|
||||||
|
|
||||||
|
package blake2b
|
||||||
|
|
||||||
|
import "golang.org/x/sys/cpu"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
useAVX2 = cpu.X86.HasAVX2
|
||||||
|
useAVX = cpu.X86.HasAVX
|
||||||
|
useSSE4 = cpu.X86.HasSSE41
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||||
|
|
||||||
|
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
|
||||||
|
switch {
|
||||||
|
case useAVX2:
|
||||||
|
hashBlocksAVX2(h, c, flag, blocks)
|
||||||
|
case useAVX:
|
||||||
|
hashBlocksAVX(h, c, flag, blocks)
|
||||||
|
case useSSE4:
|
||||||
|
hashBlocksSSE4(h, c, flag, blocks)
|
||||||
|
default:
|
||||||
|
hashBlocksGeneric(h, c, flag, blocks)
|
||||||
|
}
|
||||||
|
}
|
744
cli/v2/picocrypt/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
generated
vendored
Normal file
744
cli/v2/picocrypt/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,744 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build amd64 && gc && !purego
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
DATA ·AVX2_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
|
||||||
|
DATA ·AVX2_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
|
||||||
|
DATA ·AVX2_iv0<>+0x10(SB)/8, $0x3c6ef372fe94f82b
|
||||||
|
DATA ·AVX2_iv0<>+0x18(SB)/8, $0xa54ff53a5f1d36f1
|
||||||
|
GLOBL ·AVX2_iv0<>(SB), (NOPTR+RODATA), $32
|
||||||
|
|
||||||
|
DATA ·AVX2_iv1<>+0x00(SB)/8, $0x510e527fade682d1
|
||||||
|
DATA ·AVX2_iv1<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
|
||||||
|
DATA ·AVX2_iv1<>+0x10(SB)/8, $0x1f83d9abfb41bd6b
|
||||||
|
DATA ·AVX2_iv1<>+0x18(SB)/8, $0x5be0cd19137e2179
|
||||||
|
GLOBL ·AVX2_iv1<>(SB), (NOPTR+RODATA), $32
|
||||||
|
|
||||||
|
DATA ·AVX2_c40<>+0x00(SB)/8, $0x0201000706050403
|
||||||
|
DATA ·AVX2_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
|
||||||
|
DATA ·AVX2_c40<>+0x10(SB)/8, $0x0201000706050403
|
||||||
|
DATA ·AVX2_c40<>+0x18(SB)/8, $0x0a09080f0e0d0c0b
|
||||||
|
GLOBL ·AVX2_c40<>(SB), (NOPTR+RODATA), $32
|
||||||
|
|
||||||
|
DATA ·AVX2_c48<>+0x00(SB)/8, $0x0100070605040302
|
||||||
|
DATA ·AVX2_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
|
||||||
|
DATA ·AVX2_c48<>+0x10(SB)/8, $0x0100070605040302
|
||||||
|
DATA ·AVX2_c48<>+0x18(SB)/8, $0x09080f0e0d0c0b0a
|
||||||
|
GLOBL ·AVX2_c48<>(SB), (NOPTR+RODATA), $32
|
||||||
|
|
||||||
|
DATA ·AVX_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
|
||||||
|
DATA ·AVX_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
|
||||||
|
GLOBL ·AVX_iv0<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
DATA ·AVX_iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b
|
||||||
|
DATA ·AVX_iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1
|
||||||
|
GLOBL ·AVX_iv1<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
DATA ·AVX_iv2<>+0x00(SB)/8, $0x510e527fade682d1
|
||||||
|
DATA ·AVX_iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
|
||||||
|
GLOBL ·AVX_iv2<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
DATA ·AVX_iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b
|
||||||
|
DATA ·AVX_iv3<>+0x08(SB)/8, $0x5be0cd19137e2179
|
||||||
|
GLOBL ·AVX_iv3<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
DATA ·AVX_c40<>+0x00(SB)/8, $0x0201000706050403
|
||||||
|
DATA ·AVX_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
|
||||||
|
GLOBL ·AVX_c40<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
DATA ·AVX_c48<>+0x00(SB)/8, $0x0100070605040302
|
||||||
|
DATA ·AVX_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
|
||||||
|
GLOBL ·AVX_c48<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
#define VPERMQ_0x39_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x39
|
||||||
|
#define VPERMQ_0x93_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x93
|
||||||
|
#define VPERMQ_0x4E_Y2_Y2 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2; BYTE $0x4e
|
||||||
|
#define VPERMQ_0x93_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x93
|
||||||
|
#define VPERMQ_0x39_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x39
|
||||||
|
|
||||||
|
#define ROUND_AVX2(m0, m1, m2, m3, t, c40, c48) \
|
||||||
|
VPADDQ m0, Y0, Y0; \
|
||||||
|
VPADDQ Y1, Y0, Y0; \
|
||||||
|
VPXOR Y0, Y3, Y3; \
|
||||||
|
VPSHUFD $-79, Y3, Y3; \
|
||||||
|
VPADDQ Y3, Y2, Y2; \
|
||||||
|
VPXOR Y2, Y1, Y1; \
|
||||||
|
VPSHUFB c40, Y1, Y1; \
|
||||||
|
VPADDQ m1, Y0, Y0; \
|
||||||
|
VPADDQ Y1, Y0, Y0; \
|
||||||
|
VPXOR Y0, Y3, Y3; \
|
||||||
|
VPSHUFB c48, Y3, Y3; \
|
||||||
|
VPADDQ Y3, Y2, Y2; \
|
||||||
|
VPXOR Y2, Y1, Y1; \
|
||||||
|
VPADDQ Y1, Y1, t; \
|
||||||
|
VPSRLQ $63, Y1, Y1; \
|
||||||
|
VPXOR t, Y1, Y1; \
|
||||||
|
VPERMQ_0x39_Y1_Y1; \
|
||||||
|
VPERMQ_0x4E_Y2_Y2; \
|
||||||
|
VPERMQ_0x93_Y3_Y3; \
|
||||||
|
VPADDQ m2, Y0, Y0; \
|
||||||
|
VPADDQ Y1, Y0, Y0; \
|
||||||
|
VPXOR Y0, Y3, Y3; \
|
||||||
|
VPSHUFD $-79, Y3, Y3; \
|
||||||
|
VPADDQ Y3, Y2, Y2; \
|
||||||
|
VPXOR Y2, Y1, Y1; \
|
||||||
|
VPSHUFB c40, Y1, Y1; \
|
||||||
|
VPADDQ m3, Y0, Y0; \
|
||||||
|
VPADDQ Y1, Y0, Y0; \
|
||||||
|
VPXOR Y0, Y3, Y3; \
|
||||||
|
VPSHUFB c48, Y3, Y3; \
|
||||||
|
VPADDQ Y3, Y2, Y2; \
|
||||||
|
VPXOR Y2, Y1, Y1; \
|
||||||
|
VPADDQ Y1, Y1, t; \
|
||||||
|
VPSRLQ $63, Y1, Y1; \
|
||||||
|
VPXOR t, Y1, Y1; \
|
||||||
|
VPERMQ_0x39_Y3_Y3; \
|
||||||
|
VPERMQ_0x4E_Y2_Y2; \
|
||||||
|
VPERMQ_0x93_Y1_Y1
|
||||||
|
|
||||||
|
#define VMOVQ_SI_X11_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x1E
|
||||||
|
#define VMOVQ_SI_X12_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x26
|
||||||
|
#define VMOVQ_SI_X13_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x2E
|
||||||
|
#define VMOVQ_SI_X14_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x36
|
||||||
|
#define VMOVQ_SI_X15_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x3E
|
||||||
|
|
||||||
|
#define VMOVQ_SI_X11(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x5E; BYTE $n
|
||||||
|
#define VMOVQ_SI_X12(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x66; BYTE $n
|
||||||
|
#define VMOVQ_SI_X13(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x6E; BYTE $n
|
||||||
|
#define VMOVQ_SI_X14(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x76; BYTE $n
|
||||||
|
#define VMOVQ_SI_X15(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x7E; BYTE $n
|
||||||
|
|
||||||
|
#define VPINSRQ_1_SI_X11_0 BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x1E; BYTE $0x01
|
||||||
|
#define VPINSRQ_1_SI_X12_0 BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x26; BYTE $0x01
|
||||||
|
#define VPINSRQ_1_SI_X13_0 BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x2E; BYTE $0x01
|
||||||
|
#define VPINSRQ_1_SI_X14_0 BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x36; BYTE $0x01
|
||||||
|
#define VPINSRQ_1_SI_X15_0 BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x3E; BYTE $0x01
|
||||||
|
|
||||||
|
#define VPINSRQ_1_SI_X11(n) BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x5E; BYTE $n; BYTE $0x01
|
||||||
|
#define VPINSRQ_1_SI_X12(n) BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x66; BYTE $n; BYTE $0x01
|
||||||
|
#define VPINSRQ_1_SI_X13(n) BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x6E; BYTE $n; BYTE $0x01
|
||||||
|
#define VPINSRQ_1_SI_X14(n) BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x76; BYTE $n; BYTE $0x01
|
||||||
|
#define VPINSRQ_1_SI_X15(n) BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x7E; BYTE $n; BYTE $0x01
|
||||||
|
|
||||||
|
#define VMOVQ_R8_X15 BYTE $0xC4; BYTE $0x41; BYTE $0xF9; BYTE $0x6E; BYTE $0xF8
|
||||||
|
#define VPINSRQ_1_R9_X15 BYTE $0xC4; BYTE $0x43; BYTE $0x81; BYTE $0x22; BYTE $0xF9; BYTE $0x01
|
||||||
|
|
||||||
|
// load msg: Y12 = (i0, i1, i2, i3)
|
||||||
|
// i0, i1, i2, i3 must not be 0
|
||||||
|
#define LOAD_MSG_AVX2_Y12(i0, i1, i2, i3) \
|
||||||
|
VMOVQ_SI_X12(i0*8); \
|
||||||
|
VMOVQ_SI_X11(i2*8); \
|
||||||
|
VPINSRQ_1_SI_X12(i1*8); \
|
||||||
|
VPINSRQ_1_SI_X11(i3*8); \
|
||||||
|
VINSERTI128 $1, X11, Y12, Y12
|
||||||
|
|
||||||
|
// load msg: Y13 = (i0, i1, i2, i3)
|
||||||
|
// i0, i1, i2, i3 must not be 0
|
||||||
|
#define LOAD_MSG_AVX2_Y13(i0, i1, i2, i3) \
|
||||||
|
VMOVQ_SI_X13(i0*8); \
|
||||||
|
VMOVQ_SI_X11(i2*8); \
|
||||||
|
VPINSRQ_1_SI_X13(i1*8); \
|
||||||
|
VPINSRQ_1_SI_X11(i3*8); \
|
||||||
|
VINSERTI128 $1, X11, Y13, Y13
|
||||||
|
|
||||||
|
// load msg: Y14 = (i0, i1, i2, i3)
|
||||||
|
// i0, i1, i2, i3 must not be 0
|
||||||
|
#define LOAD_MSG_AVX2_Y14(i0, i1, i2, i3) \
|
||||||
|
VMOVQ_SI_X14(i0*8); \
|
||||||
|
VMOVQ_SI_X11(i2*8); \
|
||||||
|
VPINSRQ_1_SI_X14(i1*8); \
|
||||||
|
VPINSRQ_1_SI_X11(i3*8); \
|
||||||
|
VINSERTI128 $1, X11, Y14, Y14
|
||||||
|
|
||||||
|
// load msg: Y15 = (i0, i1, i2, i3)
|
||||||
|
// i0, i1, i2, i3 must not be 0
|
||||||
|
#define LOAD_MSG_AVX2_Y15(i0, i1, i2, i3) \
|
||||||
|
VMOVQ_SI_X15(i0*8); \
|
||||||
|
VMOVQ_SI_X11(i2*8); \
|
||||||
|
VPINSRQ_1_SI_X15(i1*8); \
|
||||||
|
VPINSRQ_1_SI_X11(i3*8); \
|
||||||
|
VINSERTI128 $1, X11, Y15, Y15
|
||||||
|
|
||||||
|
#define LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15() \
|
||||||
|
VMOVQ_SI_X12_0; \
|
||||||
|
VMOVQ_SI_X11(4*8); \
|
||||||
|
VPINSRQ_1_SI_X12(2*8); \
|
||||||
|
VPINSRQ_1_SI_X11(6*8); \
|
||||||
|
VINSERTI128 $1, X11, Y12, Y12; \
|
||||||
|
LOAD_MSG_AVX2_Y13(1, 3, 5, 7); \
|
||||||
|
LOAD_MSG_AVX2_Y14(8, 10, 12, 14); \
|
||||||
|
LOAD_MSG_AVX2_Y15(9, 11, 13, 15)
|
||||||
|
|
||||||
|
#define LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3() \
|
||||||
|
LOAD_MSG_AVX2_Y12(14, 4, 9, 13); \
|
||||||
|
LOAD_MSG_AVX2_Y13(10, 8, 15, 6); \
|
||||||
|
VMOVQ_SI_X11(11*8); \
|
||||||
|
VPSHUFD $0x4E, 0*8(SI), X14; \
|
||||||
|
VPINSRQ_1_SI_X11(5*8); \
|
||||||
|
VINSERTI128 $1, X11, Y14, Y14; \
|
||||||
|
LOAD_MSG_AVX2_Y15(12, 2, 7, 3)
|
||||||
|
|
||||||
|
#define LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4() \
|
||||||
|
VMOVQ_SI_X11(5*8); \
|
||||||
|
VMOVDQU 11*8(SI), X12; \
|
||||||
|
VPINSRQ_1_SI_X11(15*8); \
|
||||||
|
VINSERTI128 $1, X11, Y12, Y12; \
|
||||||
|
VMOVQ_SI_X13(8*8); \
|
||||||
|
VMOVQ_SI_X11(2*8); \
|
||||||
|
VPINSRQ_1_SI_X13_0; \
|
||||||
|
VPINSRQ_1_SI_X11(13*8); \
|
||||||
|
VINSERTI128 $1, X11, Y13, Y13; \
|
||||||
|
LOAD_MSG_AVX2_Y14(10, 3, 7, 9); \
|
||||||
|
LOAD_MSG_AVX2_Y15(14, 6, 1, 4)
|
||||||
|
|
||||||
|
#define LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8() \
|
||||||
|
LOAD_MSG_AVX2_Y12(7, 3, 13, 11); \
|
||||||
|
LOAD_MSG_AVX2_Y13(9, 1, 12, 14); \
|
||||||
|
LOAD_MSG_AVX2_Y14(2, 5, 4, 15); \
|
||||||
|
VMOVQ_SI_X15(6*8); \
|
||||||
|
VMOVQ_SI_X11_0; \
|
||||||
|
VPINSRQ_1_SI_X15(10*8); \
|
||||||
|
VPINSRQ_1_SI_X11(8*8); \
|
||||||
|
VINSERTI128 $1, X11, Y15, Y15
|
||||||
|
|
||||||
|
#define LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13() \
|
||||||
|
LOAD_MSG_AVX2_Y12(9, 5, 2, 10); \
|
||||||
|
VMOVQ_SI_X13_0; \
|
||||||
|
VMOVQ_SI_X11(4*8); \
|
||||||
|
VPINSRQ_1_SI_X13(7*8); \
|
||||||
|
VPINSRQ_1_SI_X11(15*8); \
|
||||||
|
VINSERTI128 $1, X11, Y13, Y13; \
|
||||||
|
LOAD_MSG_AVX2_Y14(14, 11, 6, 3); \
|
||||||
|
LOAD_MSG_AVX2_Y15(1, 12, 8, 13)
|
||||||
|
|
||||||
|
#define LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9() \
|
||||||
|
VMOVQ_SI_X12(2*8); \
|
||||||
|
VMOVQ_SI_X11_0; \
|
||||||
|
VPINSRQ_1_SI_X12(6*8); \
|
||||||
|
VPINSRQ_1_SI_X11(8*8); \
|
||||||
|
VINSERTI128 $1, X11, Y12, Y12; \
|
||||||
|
LOAD_MSG_AVX2_Y13(12, 10, 11, 3); \
|
||||||
|
LOAD_MSG_AVX2_Y14(4, 7, 15, 1); \
|
||||||
|
LOAD_MSG_AVX2_Y15(13, 5, 14, 9)
|
||||||
|
|
||||||
|
#define LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11() \
|
||||||
|
LOAD_MSG_AVX2_Y12(12, 1, 14, 4); \
|
||||||
|
LOAD_MSG_AVX2_Y13(5, 15, 13, 10); \
|
||||||
|
VMOVQ_SI_X14_0; \
|
||||||
|
VPSHUFD $0x4E, 8*8(SI), X11; \
|
||||||
|
VPINSRQ_1_SI_X14(6*8); \
|
||||||
|
VINSERTI128 $1, X11, Y14, Y14; \
|
||||||
|
LOAD_MSG_AVX2_Y15(7, 3, 2, 11)
|
||||||
|
|
||||||
|
#define LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10() \
|
||||||
|
LOAD_MSG_AVX2_Y12(13, 7, 12, 3); \
|
||||||
|
LOAD_MSG_AVX2_Y13(11, 14, 1, 9); \
|
||||||
|
LOAD_MSG_AVX2_Y14(5, 15, 8, 2); \
|
||||||
|
VMOVQ_SI_X15_0; \
|
||||||
|
VMOVQ_SI_X11(6*8); \
|
||||||
|
VPINSRQ_1_SI_X15(4*8); \
|
||||||
|
VPINSRQ_1_SI_X11(10*8); \
|
||||||
|
VINSERTI128 $1, X11, Y15, Y15
|
||||||
|
|
||||||
|
#define LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5() \
|
||||||
|
VMOVQ_SI_X12(6*8); \
|
||||||
|
VMOVQ_SI_X11(11*8); \
|
||||||
|
VPINSRQ_1_SI_X12(14*8); \
|
||||||
|
VPINSRQ_1_SI_X11_0; \
|
||||||
|
VINSERTI128 $1, X11, Y12, Y12; \
|
||||||
|
LOAD_MSG_AVX2_Y13(15, 9, 3, 8); \
|
||||||
|
VMOVQ_SI_X11(1*8); \
|
||||||
|
VMOVDQU 12*8(SI), X14; \
|
||||||
|
VPINSRQ_1_SI_X11(10*8); \
|
||||||
|
VINSERTI128 $1, X11, Y14, Y14; \
|
||||||
|
VMOVQ_SI_X15(2*8); \
|
||||||
|
VMOVDQU 4*8(SI), X11; \
|
||||||
|
VPINSRQ_1_SI_X15(7*8); \
|
||||||
|
VINSERTI128 $1, X11, Y15, Y15
|
||||||
|
|
||||||
|
#define LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0() \
|
||||||
|
LOAD_MSG_AVX2_Y12(10, 8, 7, 1); \
|
||||||
|
VMOVQ_SI_X13(2*8); \
|
||||||
|
VPSHUFD $0x4E, 5*8(SI), X11; \
|
||||||
|
VPINSRQ_1_SI_X13(4*8); \
|
||||||
|
VINSERTI128 $1, X11, Y13, Y13; \
|
||||||
|
LOAD_MSG_AVX2_Y14(15, 9, 3, 13); \
|
||||||
|
VMOVQ_SI_X15(11*8); \
|
||||||
|
VMOVQ_SI_X11(12*8); \
|
||||||
|
VPINSRQ_1_SI_X15(14*8); \
|
||||||
|
VPINSRQ_1_SI_X11_0; \
|
||||||
|
VINSERTI128 $1, X11, Y15, Y15
|
||||||
|
|
||||||
|
// func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||||
|
TEXT ·hashBlocksAVX2(SB), 4, $320-48 // frame size = 288 + 32 byte alignment
|
||||||
|
MOVQ h+0(FP), AX
|
||||||
|
MOVQ c+8(FP), BX
|
||||||
|
MOVQ flag+16(FP), CX
|
||||||
|
MOVQ blocks_base+24(FP), SI
|
||||||
|
MOVQ blocks_len+32(FP), DI
|
||||||
|
|
||||||
|
MOVQ SP, DX
|
||||||
|
ADDQ $31, DX
|
||||||
|
ANDQ $~31, DX
|
||||||
|
|
||||||
|
MOVQ CX, 16(DX)
|
||||||
|
XORQ CX, CX
|
||||||
|
MOVQ CX, 24(DX)
|
||||||
|
|
||||||
|
VMOVDQU ·AVX2_c40<>(SB), Y4
|
||||||
|
VMOVDQU ·AVX2_c48<>(SB), Y5
|
||||||
|
|
||||||
|
VMOVDQU 0(AX), Y8
|
||||||
|
VMOVDQU 32(AX), Y9
|
||||||
|
VMOVDQU ·AVX2_iv0<>(SB), Y6
|
||||||
|
VMOVDQU ·AVX2_iv1<>(SB), Y7
|
||||||
|
|
||||||
|
MOVQ 0(BX), R8
|
||||||
|
MOVQ 8(BX), R9
|
||||||
|
MOVQ R9, 8(DX)
|
||||||
|
|
||||||
|
loop:
|
||||||
|
ADDQ $128, R8
|
||||||
|
MOVQ R8, 0(DX)
|
||||||
|
CMPQ R8, $128
|
||||||
|
JGE noinc
|
||||||
|
INCQ R9
|
||||||
|
MOVQ R9, 8(DX)
|
||||||
|
|
||||||
|
noinc:
|
||||||
|
VMOVDQA Y8, Y0
|
||||||
|
VMOVDQA Y9, Y1
|
||||||
|
VMOVDQA Y6, Y2
|
||||||
|
VPXOR 0(DX), Y7, Y3
|
||||||
|
|
||||||
|
LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15()
|
||||||
|
VMOVDQA Y12, 32(DX)
|
||||||
|
VMOVDQA Y13, 64(DX)
|
||||||
|
VMOVDQA Y14, 96(DX)
|
||||||
|
VMOVDQA Y15, 128(DX)
|
||||||
|
ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
|
||||||
|
LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3()
|
||||||
|
VMOVDQA Y12, 160(DX)
|
||||||
|
VMOVDQA Y13, 192(DX)
|
||||||
|
VMOVDQA Y14, 224(DX)
|
||||||
|
VMOVDQA Y15, 256(DX)
|
||||||
|
|
||||||
|
ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
|
||||||
|
LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4()
|
||||||
|
ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
|
||||||
|
LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8()
|
||||||
|
ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
|
||||||
|
LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13()
|
||||||
|
ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
|
||||||
|
LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9()
|
||||||
|
ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
|
||||||
|
LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11()
|
||||||
|
ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
|
||||||
|
LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10()
|
||||||
|
ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
|
||||||
|
LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5()
|
||||||
|
ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
|
||||||
|
LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0()
|
||||||
|
ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
|
||||||
|
|
||||||
|
ROUND_AVX2(32(DX), 64(DX), 96(DX), 128(DX), Y10, Y4, Y5)
|
||||||
|
ROUND_AVX2(160(DX), 192(DX), 224(DX), 256(DX), Y10, Y4, Y5)
|
||||||
|
|
||||||
|
VPXOR Y0, Y8, Y8
|
||||||
|
VPXOR Y1, Y9, Y9
|
||||||
|
VPXOR Y2, Y8, Y8
|
||||||
|
VPXOR Y3, Y9, Y9
|
||||||
|
|
||||||
|
LEAQ 128(SI), SI
|
||||||
|
SUBQ $128, DI
|
||||||
|
JNE loop
|
||||||
|
|
||||||
|
MOVQ R8, 0(BX)
|
||||||
|
MOVQ R9, 8(BX)
|
||||||
|
|
||||||
|
VMOVDQU Y8, 0(AX)
|
||||||
|
VMOVDQU Y9, 32(AX)
|
||||||
|
VZEROUPPER
|
||||||
|
|
||||||
|
RET
|
||||||
|
|
||||||
|
#define VPUNPCKLQDQ_X2_X2_X15 BYTE $0xC5; BYTE $0x69; BYTE $0x6C; BYTE $0xFA
|
||||||
|
#define VPUNPCKLQDQ_X3_X3_X15 BYTE $0xC5; BYTE $0x61; BYTE $0x6C; BYTE $0xFB
|
||||||
|
#define VPUNPCKLQDQ_X7_X7_X15 BYTE $0xC5; BYTE $0x41; BYTE $0x6C; BYTE $0xFF
|
||||||
|
#define VPUNPCKLQDQ_X13_X13_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x11; BYTE $0x6C; BYTE $0xFD
|
||||||
|
#define VPUNPCKLQDQ_X14_X14_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x09; BYTE $0x6C; BYTE $0xFE
|
||||||
|
|
||||||
|
#define VPUNPCKHQDQ_X15_X2_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x69; BYTE $0x6D; BYTE $0xD7
|
||||||
|
#define VPUNPCKHQDQ_X15_X3_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xDF
|
||||||
|
#define VPUNPCKHQDQ_X15_X6_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x49; BYTE $0x6D; BYTE $0xF7
|
||||||
|
#define VPUNPCKHQDQ_X15_X7_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xFF
|
||||||
|
#define VPUNPCKHQDQ_X15_X3_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xD7
|
||||||
|
#define VPUNPCKHQDQ_X15_X7_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xF7
|
||||||
|
#define VPUNPCKHQDQ_X15_X13_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xDF
|
||||||
|
#define VPUNPCKHQDQ_X15_X13_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xFF
|
||||||
|
|
||||||
|
#define SHUFFLE_AVX() \
|
||||||
|
VMOVDQA X6, X13; \
|
||||||
|
VMOVDQA X2, X14; \
|
||||||
|
VMOVDQA X4, X6; \
|
||||||
|
VPUNPCKLQDQ_X13_X13_X15; \
|
||||||
|
VMOVDQA X5, X4; \
|
||||||
|
VMOVDQA X6, X5; \
|
||||||
|
VPUNPCKHQDQ_X15_X7_X6; \
|
||||||
|
VPUNPCKLQDQ_X7_X7_X15; \
|
||||||
|
VPUNPCKHQDQ_X15_X13_X7; \
|
||||||
|
VPUNPCKLQDQ_X3_X3_X15; \
|
||||||
|
VPUNPCKHQDQ_X15_X2_X2; \
|
||||||
|
VPUNPCKLQDQ_X14_X14_X15; \
|
||||||
|
VPUNPCKHQDQ_X15_X3_X3; \
|
||||||
|
|
||||||
|
#define SHUFFLE_AVX_INV() \
|
||||||
|
VMOVDQA X2, X13; \
|
||||||
|
VMOVDQA X4, X14; \
|
||||||
|
VPUNPCKLQDQ_X2_X2_X15; \
|
||||||
|
VMOVDQA X5, X4; \
|
||||||
|
VPUNPCKHQDQ_X15_X3_X2; \
|
||||||
|
VMOVDQA X14, X5; \
|
||||||
|
VPUNPCKLQDQ_X3_X3_X15; \
|
||||||
|
VMOVDQA X6, X14; \
|
||||||
|
VPUNPCKHQDQ_X15_X13_X3; \
|
||||||
|
VPUNPCKLQDQ_X7_X7_X15; \
|
||||||
|
VPUNPCKHQDQ_X15_X6_X6; \
|
||||||
|
VPUNPCKLQDQ_X14_X14_X15; \
|
||||||
|
VPUNPCKHQDQ_X15_X7_X7; \
|
||||||
|
|
||||||
|
#define HALF_ROUND_AVX(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \
|
||||||
|
VPADDQ m0, v0, v0; \
|
||||||
|
VPADDQ v2, v0, v0; \
|
||||||
|
VPADDQ m1, v1, v1; \
|
||||||
|
VPADDQ v3, v1, v1; \
|
||||||
|
VPXOR v0, v6, v6; \
|
||||||
|
VPXOR v1, v7, v7; \
|
||||||
|
VPSHUFD $-79, v6, v6; \
|
||||||
|
VPSHUFD $-79, v7, v7; \
|
||||||
|
VPADDQ v6, v4, v4; \
|
||||||
|
VPADDQ v7, v5, v5; \
|
||||||
|
VPXOR v4, v2, v2; \
|
||||||
|
VPXOR v5, v3, v3; \
|
||||||
|
VPSHUFB c40, v2, v2; \
|
||||||
|
VPSHUFB c40, v3, v3; \
|
||||||
|
VPADDQ m2, v0, v0; \
|
||||||
|
VPADDQ v2, v0, v0; \
|
||||||
|
VPADDQ m3, v1, v1; \
|
||||||
|
VPADDQ v3, v1, v1; \
|
||||||
|
VPXOR v0, v6, v6; \
|
||||||
|
VPXOR v1, v7, v7; \
|
||||||
|
VPSHUFB c48, v6, v6; \
|
||||||
|
VPSHUFB c48, v7, v7; \
|
||||||
|
VPADDQ v6, v4, v4; \
|
||||||
|
VPADDQ v7, v5, v5; \
|
||||||
|
VPXOR v4, v2, v2; \
|
||||||
|
VPXOR v5, v3, v3; \
|
||||||
|
VPADDQ v2, v2, t0; \
|
||||||
|
VPSRLQ $63, v2, v2; \
|
||||||
|
VPXOR t0, v2, v2; \
|
||||||
|
VPADDQ v3, v3, t0; \
|
||||||
|
VPSRLQ $63, v3, v3; \
|
||||||
|
VPXOR t0, v3, v3
|
||||||
|
|
||||||
|
// load msg: X12 = (i0, i1), X13 = (i2, i3), X14 = (i4, i5), X15 = (i6, i7)
|
||||||
|
// i0, i1, i2, i3, i4, i5, i6, i7 must not be 0
|
||||||
|
#define LOAD_MSG_AVX(i0, i1, i2, i3, i4, i5, i6, i7) \
|
||||||
|
VMOVQ_SI_X12(i0*8); \
|
||||||
|
VMOVQ_SI_X13(i2*8); \
|
||||||
|
VMOVQ_SI_X14(i4*8); \
|
||||||
|
VMOVQ_SI_X15(i6*8); \
|
||||||
|
VPINSRQ_1_SI_X12(i1*8); \
|
||||||
|
VPINSRQ_1_SI_X13(i3*8); \
|
||||||
|
VPINSRQ_1_SI_X14(i5*8); \
|
||||||
|
VPINSRQ_1_SI_X15(i7*8)
|
||||||
|
|
||||||
|
// load msg: X12 = (0, 2), X13 = (4, 6), X14 = (1, 3), X15 = (5, 7)
|
||||||
|
#define LOAD_MSG_AVX_0_2_4_6_1_3_5_7() \
|
||||||
|
VMOVQ_SI_X12_0; \
|
||||||
|
VMOVQ_SI_X13(4*8); \
|
||||||
|
VMOVQ_SI_X14(1*8); \
|
||||||
|
VMOVQ_SI_X15(5*8); \
|
||||||
|
VPINSRQ_1_SI_X12(2*8); \
|
||||||
|
VPINSRQ_1_SI_X13(6*8); \
|
||||||
|
VPINSRQ_1_SI_X14(3*8); \
|
||||||
|
VPINSRQ_1_SI_X15(7*8)
|
||||||
|
|
||||||
|
// load msg: X12 = (1, 0), X13 = (11, 5), X14 = (12, 2), X15 = (7, 3)
|
||||||
|
#define LOAD_MSG_AVX_1_0_11_5_12_2_7_3() \
|
||||||
|
VPSHUFD $0x4E, 0*8(SI), X12; \
|
||||||
|
VMOVQ_SI_X13(11*8); \
|
||||||
|
VMOVQ_SI_X14(12*8); \
|
||||||
|
VMOVQ_SI_X15(7*8); \
|
||||||
|
VPINSRQ_1_SI_X13(5*8); \
|
||||||
|
VPINSRQ_1_SI_X14(2*8); \
|
||||||
|
VPINSRQ_1_SI_X15(3*8)
|
||||||
|
|
||||||
|
// load msg: X12 = (11, 12), X13 = (5, 15), X14 = (8, 0), X15 = (2, 13)
|
||||||
|
#define LOAD_MSG_AVX_11_12_5_15_8_0_2_13() \
|
||||||
|
VMOVDQU 11*8(SI), X12; \
|
||||||
|
VMOVQ_SI_X13(5*8); \
|
||||||
|
VMOVQ_SI_X14(8*8); \
|
||||||
|
VMOVQ_SI_X15(2*8); \
|
||||||
|
VPINSRQ_1_SI_X13(15*8); \
|
||||||
|
VPINSRQ_1_SI_X14_0; \
|
||||||
|
VPINSRQ_1_SI_X15(13*8)
|
||||||
|
|
||||||
|
// load msg: X12 = (2, 5), X13 = (4, 15), X14 = (6, 10), X15 = (0, 8)
|
||||||
|
#define LOAD_MSG_AVX_2_5_4_15_6_10_0_8() \
|
||||||
|
VMOVQ_SI_X12(2*8); \
|
||||||
|
VMOVQ_SI_X13(4*8); \
|
||||||
|
VMOVQ_SI_X14(6*8); \
|
||||||
|
VMOVQ_SI_X15_0; \
|
||||||
|
VPINSRQ_1_SI_X12(5*8); \
|
||||||
|
VPINSRQ_1_SI_X13(15*8); \
|
||||||
|
VPINSRQ_1_SI_X14(10*8); \
|
||||||
|
VPINSRQ_1_SI_X15(8*8)
|
||||||
|
|
||||||
|
// load msg: X12 = (9, 5), X13 = (2, 10), X14 = (0, 7), X15 = (4, 15)
|
||||||
|
#define LOAD_MSG_AVX_9_5_2_10_0_7_4_15() \
|
||||||
|
VMOVQ_SI_X12(9*8); \
|
||||||
|
VMOVQ_SI_X13(2*8); \
|
||||||
|
VMOVQ_SI_X14_0; \
|
||||||
|
VMOVQ_SI_X15(4*8); \
|
||||||
|
VPINSRQ_1_SI_X12(5*8); \
|
||||||
|
VPINSRQ_1_SI_X13(10*8); \
|
||||||
|
VPINSRQ_1_SI_X14(7*8); \
|
||||||
|
VPINSRQ_1_SI_X15(15*8)
|
||||||
|
|
||||||
|
// load msg: X12 = (2, 6), X13 = (0, 8), X14 = (12, 10), X15 = (11, 3)
|
||||||
|
#define LOAD_MSG_AVX_2_6_0_8_12_10_11_3() \
|
||||||
|
VMOVQ_SI_X12(2*8); \
|
||||||
|
VMOVQ_SI_X13_0; \
|
||||||
|
VMOVQ_SI_X14(12*8); \
|
||||||
|
VMOVQ_SI_X15(11*8); \
|
||||||
|
VPINSRQ_1_SI_X12(6*8); \
|
||||||
|
VPINSRQ_1_SI_X13(8*8); \
|
||||||
|
VPINSRQ_1_SI_X14(10*8); \
|
||||||
|
VPINSRQ_1_SI_X15(3*8)
|
||||||
|
|
||||||
|
// load msg: X12 = (0, 6), X13 = (9, 8), X14 = (7, 3), X15 = (2, 11)
|
||||||
|
#define LOAD_MSG_AVX_0_6_9_8_7_3_2_11() \
|
||||||
|
MOVQ 0*8(SI), X12; \
|
||||||
|
VPSHUFD $0x4E, 8*8(SI), X13; \
|
||||||
|
MOVQ 7*8(SI), X14; \
|
||||||
|
MOVQ 2*8(SI), X15; \
|
||||||
|
VPINSRQ_1_SI_X12(6*8); \
|
||||||
|
VPINSRQ_1_SI_X14(3*8); \
|
||||||
|
VPINSRQ_1_SI_X15(11*8)
|
||||||
|
|
||||||
|
// load msg: X12 = (6, 14), X13 = (11, 0), X14 = (15, 9), X15 = (3, 8)
|
||||||
|
#define LOAD_MSG_AVX_6_14_11_0_15_9_3_8() \
|
||||||
|
MOVQ 6*8(SI), X12; \
|
||||||
|
MOVQ 11*8(SI), X13; \
|
||||||
|
MOVQ 15*8(SI), X14; \
|
||||||
|
MOVQ 3*8(SI), X15; \
|
||||||
|
VPINSRQ_1_SI_X12(14*8); \
|
||||||
|
VPINSRQ_1_SI_X13_0; \
|
||||||
|
VPINSRQ_1_SI_X14(9*8); \
|
||||||
|
VPINSRQ_1_SI_X15(8*8)
|
||||||
|
|
||||||
|
// load msg: X12 = (5, 15), X13 = (8, 2), X14 = (0, 4), X15 = (6, 10)
|
||||||
|
#define LOAD_MSG_AVX_5_15_8_2_0_4_6_10() \
|
||||||
|
MOVQ 5*8(SI), X12; \
|
||||||
|
MOVQ 8*8(SI), X13; \
|
||||||
|
MOVQ 0*8(SI), X14; \
|
||||||
|
MOVQ 6*8(SI), X15; \
|
||||||
|
VPINSRQ_1_SI_X12(15*8); \
|
||||||
|
VPINSRQ_1_SI_X13(2*8); \
|
||||||
|
VPINSRQ_1_SI_X14(4*8); \
|
||||||
|
VPINSRQ_1_SI_X15(10*8)
|
||||||
|
|
||||||
|
// load msg: X12 = (12, 13), X13 = (1, 10), X14 = (2, 7), X15 = (4, 5)
|
||||||
|
#define LOAD_MSG_AVX_12_13_1_10_2_7_4_5() \
|
||||||
|
VMOVDQU 12*8(SI), X12; \
|
||||||
|
MOVQ 1*8(SI), X13; \
|
||||||
|
MOVQ 2*8(SI), X14; \
|
||||||
|
VPINSRQ_1_SI_X13(10*8); \
|
||||||
|
VPINSRQ_1_SI_X14(7*8); \
|
||||||
|
VMOVDQU 4*8(SI), X15
|
||||||
|
|
||||||
|
// load msg: X12 = (15, 9), X13 = (3, 13), X14 = (11, 14), X15 = (12, 0)
|
||||||
|
#define LOAD_MSG_AVX_15_9_3_13_11_14_12_0() \
|
||||||
|
MOVQ 15*8(SI), X12; \
|
||||||
|
MOVQ 3*8(SI), X13; \
|
||||||
|
MOVQ 11*8(SI), X14; \
|
||||||
|
MOVQ 12*8(SI), X15; \
|
||||||
|
VPINSRQ_1_SI_X12(9*8); \
|
||||||
|
VPINSRQ_1_SI_X13(13*8); \
|
||||||
|
VPINSRQ_1_SI_X14(14*8); \
|
||||||
|
VPINSRQ_1_SI_X15_0
|
||||||
|
|
||||||
|
// func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||||
|
TEXT ·hashBlocksAVX(SB), 4, $288-48 // frame size = 272 + 16 byte alignment
|
||||||
|
MOVQ h+0(FP), AX
|
||||||
|
MOVQ c+8(FP), BX
|
||||||
|
MOVQ flag+16(FP), CX
|
||||||
|
MOVQ blocks_base+24(FP), SI
|
||||||
|
MOVQ blocks_len+32(FP), DI
|
||||||
|
|
||||||
|
MOVQ SP, R10
|
||||||
|
ADDQ $15, R10
|
||||||
|
ANDQ $~15, R10
|
||||||
|
|
||||||
|
VMOVDQU ·AVX_c40<>(SB), X0
|
||||||
|
VMOVDQU ·AVX_c48<>(SB), X1
|
||||||
|
VMOVDQA X0, X8
|
||||||
|
VMOVDQA X1, X9
|
||||||
|
|
||||||
|
VMOVDQU ·AVX_iv3<>(SB), X0
|
||||||
|
VMOVDQA X0, 0(R10)
|
||||||
|
XORQ CX, 0(R10) // 0(R10) = ·AVX_iv3 ^ (CX || 0)
|
||||||
|
|
||||||
|
VMOVDQU 0(AX), X10
|
||||||
|
VMOVDQU 16(AX), X11
|
||||||
|
VMOVDQU 32(AX), X2
|
||||||
|
VMOVDQU 48(AX), X3
|
||||||
|
|
||||||
|
MOVQ 0(BX), R8
|
||||||
|
MOVQ 8(BX), R9
|
||||||
|
|
||||||
|
loop:
|
||||||
|
ADDQ $128, R8
|
||||||
|
CMPQ R8, $128
|
||||||
|
JGE noinc
|
||||||
|
INCQ R9
|
||||||
|
|
||||||
|
noinc:
|
||||||
|
VMOVQ_R8_X15
|
||||||
|
VPINSRQ_1_R9_X15
|
||||||
|
|
||||||
|
VMOVDQA X10, X0
|
||||||
|
VMOVDQA X11, X1
|
||||||
|
VMOVDQU ·AVX_iv0<>(SB), X4
|
||||||
|
VMOVDQU ·AVX_iv1<>(SB), X5
|
||||||
|
VMOVDQU ·AVX_iv2<>(SB), X6
|
||||||
|
|
||||||
|
VPXOR X15, X6, X6
|
||||||
|
VMOVDQA 0(R10), X7
|
||||||
|
|
||||||
|
LOAD_MSG_AVX_0_2_4_6_1_3_5_7()
|
||||||
|
VMOVDQA X12, 16(R10)
|
||||||
|
VMOVDQA X13, 32(R10)
|
||||||
|
VMOVDQA X14, 48(R10)
|
||||||
|
VMOVDQA X15, 64(R10)
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
LOAD_MSG_AVX(8, 10, 12, 14, 9, 11, 13, 15)
|
||||||
|
VMOVDQA X12, 80(R10)
|
||||||
|
VMOVDQA X13, 96(R10)
|
||||||
|
VMOVDQA X14, 112(R10)
|
||||||
|
VMOVDQA X15, 128(R10)
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
LOAD_MSG_AVX(14, 4, 9, 13, 10, 8, 15, 6)
|
||||||
|
VMOVDQA X12, 144(R10)
|
||||||
|
VMOVDQA X13, 160(R10)
|
||||||
|
VMOVDQA X14, 176(R10)
|
||||||
|
VMOVDQA X15, 192(R10)
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
LOAD_MSG_AVX_1_0_11_5_12_2_7_3()
|
||||||
|
VMOVDQA X12, 208(R10)
|
||||||
|
VMOVDQA X13, 224(R10)
|
||||||
|
VMOVDQA X14, 240(R10)
|
||||||
|
VMOVDQA X15, 256(R10)
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
LOAD_MSG_AVX_11_12_5_15_8_0_2_13()
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
LOAD_MSG_AVX(10, 3, 7, 9, 14, 6, 1, 4)
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
LOAD_MSG_AVX(7, 3, 13, 11, 9, 1, 12, 14)
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
LOAD_MSG_AVX_2_5_4_15_6_10_0_8()
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
LOAD_MSG_AVX_9_5_2_10_0_7_4_15()
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
LOAD_MSG_AVX(14, 11, 6, 3, 1, 12, 8, 13)
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
LOAD_MSG_AVX_2_6_0_8_12_10_11_3()
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
LOAD_MSG_AVX(4, 7, 15, 1, 13, 5, 14, 9)
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
LOAD_MSG_AVX(12, 1, 14, 4, 5, 15, 13, 10)
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
LOAD_MSG_AVX_0_6_9_8_7_3_2_11()
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
LOAD_MSG_AVX(13, 7, 12, 3, 11, 14, 1, 9)
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
LOAD_MSG_AVX_5_15_8_2_0_4_6_10()
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
LOAD_MSG_AVX_6_14_11_0_15_9_3_8()
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
LOAD_MSG_AVX_12_13_1_10_2_7_4_5()
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
LOAD_MSG_AVX(10, 8, 7, 1, 2, 4, 6, 5)
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
LOAD_MSG_AVX_15_9_3_13_11_14_12_0()
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 16(R10), 32(R10), 48(R10), 64(R10), X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 80(R10), 96(R10), 112(R10), 128(R10), X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 144(R10), 160(R10), 176(R10), 192(R10), X15, X8, X9)
|
||||||
|
SHUFFLE_AVX()
|
||||||
|
HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 208(R10), 224(R10), 240(R10), 256(R10), X15, X8, X9)
|
||||||
|
SHUFFLE_AVX_INV()
|
||||||
|
|
||||||
|
VMOVDQU 32(AX), X14
|
||||||
|
VMOVDQU 48(AX), X15
|
||||||
|
VPXOR X0, X10, X10
|
||||||
|
VPXOR X1, X11, X11
|
||||||
|
VPXOR X2, X14, X14
|
||||||
|
VPXOR X3, X15, X15
|
||||||
|
VPXOR X4, X10, X10
|
||||||
|
VPXOR X5, X11, X11
|
||||||
|
VPXOR X6, X14, X2
|
||||||
|
VPXOR X7, X15, X3
|
||||||
|
VMOVDQU X2, 32(AX)
|
||||||
|
VMOVDQU X3, 48(AX)
|
||||||
|
|
||||||
|
LEAQ 128(SI), SI
|
||||||
|
SUBQ $128, DI
|
||||||
|
JNE loop
|
||||||
|
|
||||||
|
VMOVDQU X10, 0(AX)
|
||||||
|
VMOVDQU X11, 16(AX)
|
||||||
|
|
||||||
|
MOVQ R8, 0(BX)
|
||||||
|
MOVQ R9, 8(BX)
|
||||||
|
VZEROUPPER
|
||||||
|
|
||||||
|
RET
|
278
cli/v2/picocrypt/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
generated
vendored
Normal file
278
cli/v2/picocrypt/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build amd64 && gc && !purego
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
DATA ·iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
|
||||||
|
DATA ·iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
|
||||||
|
GLOBL ·iv0<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
DATA ·iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b
|
||||||
|
DATA ·iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1
|
||||||
|
GLOBL ·iv1<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
DATA ·iv2<>+0x00(SB)/8, $0x510e527fade682d1
|
||||||
|
DATA ·iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
|
||||||
|
GLOBL ·iv2<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
DATA ·iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b
|
||||||
|
DATA ·iv3<>+0x08(SB)/8, $0x5be0cd19137e2179
|
||||||
|
GLOBL ·iv3<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
DATA ·c40<>+0x00(SB)/8, $0x0201000706050403
|
||||||
|
DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
|
||||||
|
GLOBL ·c40<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
DATA ·c48<>+0x00(SB)/8, $0x0100070605040302
|
||||||
|
DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
|
||||||
|
GLOBL ·c48<>(SB), (NOPTR+RODATA), $16
|
||||||
|
|
||||||
|
#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \
|
||||||
|
MOVO v4, t1; \
|
||||||
|
MOVO v5, v4; \
|
||||||
|
MOVO t1, v5; \
|
||||||
|
MOVO v6, t1; \
|
||||||
|
PUNPCKLQDQ v6, t2; \
|
||||||
|
PUNPCKHQDQ v7, v6; \
|
||||||
|
PUNPCKHQDQ t2, v6; \
|
||||||
|
PUNPCKLQDQ v7, t2; \
|
||||||
|
MOVO t1, v7; \
|
||||||
|
MOVO v2, t1; \
|
||||||
|
PUNPCKHQDQ t2, v7; \
|
||||||
|
PUNPCKLQDQ v3, t2; \
|
||||||
|
PUNPCKHQDQ t2, v2; \
|
||||||
|
PUNPCKLQDQ t1, t2; \
|
||||||
|
PUNPCKHQDQ t2, v3
|
||||||
|
|
||||||
|
#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \
|
||||||
|
MOVO v4, t1; \
|
||||||
|
MOVO v5, v4; \
|
||||||
|
MOVO t1, v5; \
|
||||||
|
MOVO v2, t1; \
|
||||||
|
PUNPCKLQDQ v2, t2; \
|
||||||
|
PUNPCKHQDQ v3, v2; \
|
||||||
|
PUNPCKHQDQ t2, v2; \
|
||||||
|
PUNPCKLQDQ v3, t2; \
|
||||||
|
MOVO t1, v3; \
|
||||||
|
MOVO v6, t1; \
|
||||||
|
PUNPCKHQDQ t2, v3; \
|
||||||
|
PUNPCKLQDQ v7, t2; \
|
||||||
|
PUNPCKHQDQ t2, v6; \
|
||||||
|
PUNPCKLQDQ t1, t2; \
|
||||||
|
PUNPCKHQDQ t2, v7
|
||||||
|
|
||||||
|
#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \
|
||||||
|
PADDQ m0, v0; \
|
||||||
|
PADDQ m1, v1; \
|
||||||
|
PADDQ v2, v0; \
|
||||||
|
PADDQ v3, v1; \
|
||||||
|
PXOR v0, v6; \
|
||||||
|
PXOR v1, v7; \
|
||||||
|
PSHUFD $0xB1, v6, v6; \
|
||||||
|
PSHUFD $0xB1, v7, v7; \
|
||||||
|
PADDQ v6, v4; \
|
||||||
|
PADDQ v7, v5; \
|
||||||
|
PXOR v4, v2; \
|
||||||
|
PXOR v5, v3; \
|
||||||
|
PSHUFB c40, v2; \
|
||||||
|
PSHUFB c40, v3; \
|
||||||
|
PADDQ m2, v0; \
|
||||||
|
PADDQ m3, v1; \
|
||||||
|
PADDQ v2, v0; \
|
||||||
|
PADDQ v3, v1; \
|
||||||
|
PXOR v0, v6; \
|
||||||
|
PXOR v1, v7; \
|
||||||
|
PSHUFB c48, v6; \
|
||||||
|
PSHUFB c48, v7; \
|
||||||
|
PADDQ v6, v4; \
|
||||||
|
PADDQ v7, v5; \
|
||||||
|
PXOR v4, v2; \
|
||||||
|
PXOR v5, v3; \
|
||||||
|
MOVOU v2, t0; \
|
||||||
|
PADDQ v2, t0; \
|
||||||
|
PSRLQ $63, v2; \
|
||||||
|
PXOR t0, v2; \
|
||||||
|
MOVOU v3, t0; \
|
||||||
|
PADDQ v3, t0; \
|
||||||
|
PSRLQ $63, v3; \
|
||||||
|
PXOR t0, v3
|
||||||
|
|
||||||
|
#define LOAD_MSG(m0, m1, m2, m3, src, i0, i1, i2, i3, i4, i5, i6, i7) \
|
||||||
|
MOVQ i0*8(src), m0; \
|
||||||
|
PINSRQ $1, i1*8(src), m0; \
|
||||||
|
MOVQ i2*8(src), m1; \
|
||||||
|
PINSRQ $1, i3*8(src), m1; \
|
||||||
|
MOVQ i4*8(src), m2; \
|
||||||
|
PINSRQ $1, i5*8(src), m2; \
|
||||||
|
MOVQ i6*8(src), m3; \
|
||||||
|
PINSRQ $1, i7*8(src), m3
|
||||||
|
|
||||||
|
// func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||||
|
TEXT ·hashBlocksSSE4(SB), 4, $288-48 // frame size = 272 + 16 byte alignment
|
||||||
|
MOVQ h+0(FP), AX
|
||||||
|
MOVQ c+8(FP), BX
|
||||||
|
MOVQ flag+16(FP), CX
|
||||||
|
MOVQ blocks_base+24(FP), SI
|
||||||
|
MOVQ blocks_len+32(FP), DI
|
||||||
|
|
||||||
|
MOVQ SP, R10
|
||||||
|
ADDQ $15, R10
|
||||||
|
ANDQ $~15, R10
|
||||||
|
|
||||||
|
MOVOU ·iv3<>(SB), X0
|
||||||
|
MOVO X0, 0(R10)
|
||||||
|
XORQ CX, 0(R10) // 0(R10) = ·iv3 ^ (CX || 0)
|
||||||
|
|
||||||
|
MOVOU ·c40<>(SB), X13
|
||||||
|
MOVOU ·c48<>(SB), X14
|
||||||
|
|
||||||
|
MOVOU 0(AX), X12
|
||||||
|
MOVOU 16(AX), X15
|
||||||
|
|
||||||
|
MOVQ 0(BX), R8
|
||||||
|
MOVQ 8(BX), R9
|
||||||
|
|
||||||
|
loop:
|
||||||
|
ADDQ $128, R8
|
||||||
|
CMPQ R8, $128
|
||||||
|
JGE noinc
|
||||||
|
INCQ R9
|
||||||
|
|
||||||
|
noinc:
|
||||||
|
MOVQ R8, X8
|
||||||
|
PINSRQ $1, R9, X8
|
||||||
|
|
||||||
|
MOVO X12, X0
|
||||||
|
MOVO X15, X1
|
||||||
|
MOVOU 32(AX), X2
|
||||||
|
MOVOU 48(AX), X3
|
||||||
|
MOVOU ·iv0<>(SB), X4
|
||||||
|
MOVOU ·iv1<>(SB), X5
|
||||||
|
MOVOU ·iv2<>(SB), X6
|
||||||
|
|
||||||
|
PXOR X8, X6
|
||||||
|
MOVO 0(R10), X7
|
||||||
|
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7)
|
||||||
|
MOVO X8, 16(R10)
|
||||||
|
MOVO X9, 32(R10)
|
||||||
|
MOVO X10, 48(R10)
|
||||||
|
MOVO X11, 64(R10)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 8, 10, 12, 14, 9, 11, 13, 15)
|
||||||
|
MOVO X8, 80(R10)
|
||||||
|
MOVO X9, 96(R10)
|
||||||
|
MOVO X10, 112(R10)
|
||||||
|
MOVO X11, 128(R10)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6)
|
||||||
|
MOVO X8, 144(R10)
|
||||||
|
MOVO X9, 160(R10)
|
||||||
|
MOVO X10, 176(R10)
|
||||||
|
MOVO X11, 192(R10)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 1, 0, 11, 5, 12, 2, 7, 3)
|
||||||
|
MOVO X8, 208(R10)
|
||||||
|
MOVO X9, 224(R10)
|
||||||
|
MOVO X10, 240(R10)
|
||||||
|
MOVO X11, 256(R10)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 11, 12, 5, 15, 8, 0, 2, 13)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 10, 3, 7, 9, 14, 6, 1, 4)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 7, 3, 13, 11, 9, 1, 12, 14)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 2, 5, 4, 15, 6, 10, 0, 8)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 9, 5, 2, 10, 0, 7, 4, 15)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 14, 11, 6, 3, 1, 12, 8, 13)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 2, 6, 0, 8, 12, 10, 11, 3)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 4, 7, 15, 1, 13, 5, 14, 9)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 12, 1, 14, 4, 5, 15, 13, 10)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 0, 6, 9, 8, 7, 3, 2, 11)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 13, 7, 12, 3, 11, 14, 1, 9)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 5, 15, 8, 2, 0, 4, 6, 10)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 6, 14, 11, 0, 15, 9, 3, 8)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 12, 13, 1, 10, 2, 7, 4, 5)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 10, 8, 7, 1, 2, 4, 6, 5)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
LOAD_MSG(X8, X9, X10, X11, SI, 15, 9, 3, 13, 11, 14, 12, 0)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 16(R10), 32(R10), 48(R10), 64(R10), X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 80(R10), 96(R10), 112(R10), 128(R10), X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 144(R10), 160(R10), 176(R10), 192(R10), X11, X13, X14)
|
||||||
|
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 208(R10), 224(R10), 240(R10), 256(R10), X11, X13, X14)
|
||||||
|
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
|
||||||
|
|
||||||
|
MOVOU 32(AX), X10
|
||||||
|
MOVOU 48(AX), X11
|
||||||
|
PXOR X0, X12
|
||||||
|
PXOR X1, X15
|
||||||
|
PXOR X2, X10
|
||||||
|
PXOR X3, X11
|
||||||
|
PXOR X4, X12
|
||||||
|
PXOR X5, X15
|
||||||
|
PXOR X6, X10
|
||||||
|
PXOR X7, X11
|
||||||
|
MOVOU X10, 32(AX)
|
||||||
|
MOVOU X11, 48(AX)
|
||||||
|
|
||||||
|
LEAQ 128(SI), SI
|
||||||
|
SUBQ $128, DI
|
||||||
|
JNE loop
|
||||||
|
|
||||||
|
MOVOU X12, 0(AX)
|
||||||
|
MOVOU X15, 16(AX)
|
||||||
|
|
||||||
|
MOVQ R8, 0(BX)
|
||||||
|
MOVQ R9, 8(BX)
|
||||||
|
|
||||||
|
RET
|
182
cli/v2/picocrypt/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go
generated
vendored
Normal file
182
cli/v2/picocrypt/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go
generated
vendored
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package blake2b
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"math/bits"
|
||||||
|
)
|
||||||
|
|
||||||
|
// the precomputed values for BLAKE2b
|
||||||
|
// there are 12 16-byte arrays - one for each round
|
||||||
|
// the entries are calculated from the sigma constants.
|
||||||
|
var precomputed = [12][16]byte{
|
||||||
|
{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},
|
||||||
|
{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},
|
||||||
|
{11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},
|
||||||
|
{7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},
|
||||||
|
{9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},
|
||||||
|
{2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},
|
||||||
|
{12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},
|
||||||
|
{13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},
|
||||||
|
{6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},
|
||||||
|
{10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},
|
||||||
|
{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15}, // equal to the first
|
||||||
|
{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3}, // equal to the second
|
||||||
|
}
|
||||||
|
|
||||||
|
func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
|
||||||
|
var m [16]uint64
|
||||||
|
c0, c1 := c[0], c[1]
|
||||||
|
|
||||||
|
for i := 0; i < len(blocks); {
|
||||||
|
c0 += BlockSize
|
||||||
|
if c0 < BlockSize {
|
||||||
|
c1++
|
||||||
|
}
|
||||||
|
|
||||||
|
v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
|
||||||
|
v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
|
||||||
|
v12 ^= c0
|
||||||
|
v13 ^= c1
|
||||||
|
v14 ^= flag
|
||||||
|
|
||||||
|
for j := range m {
|
||||||
|
m[j] = binary.LittleEndian.Uint64(blocks[i:])
|
||||||
|
i += 8
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := range precomputed {
|
||||||
|
s := &(precomputed[j])
|
||||||
|
|
||||||
|
v0 += m[s[0]]
|
||||||
|
v0 += v4
|
||||||
|
v12 ^= v0
|
||||||
|
v12 = bits.RotateLeft64(v12, -32)
|
||||||
|
v8 += v12
|
||||||
|
v4 ^= v8
|
||||||
|
v4 = bits.RotateLeft64(v4, -24)
|
||||||
|
v1 += m[s[1]]
|
||||||
|
v1 += v5
|
||||||
|
v13 ^= v1
|
||||||
|
v13 = bits.RotateLeft64(v13, -32)
|
||||||
|
v9 += v13
|
||||||
|
v5 ^= v9
|
||||||
|
v5 = bits.RotateLeft64(v5, -24)
|
||||||
|
v2 += m[s[2]]
|
||||||
|
v2 += v6
|
||||||
|
v14 ^= v2
|
||||||
|
v14 = bits.RotateLeft64(v14, -32)
|
||||||
|
v10 += v14
|
||||||
|
v6 ^= v10
|
||||||
|
v6 = bits.RotateLeft64(v6, -24)
|
||||||
|
v3 += m[s[3]]
|
||||||
|
v3 += v7
|
||||||
|
v15 ^= v3
|
||||||
|
v15 = bits.RotateLeft64(v15, -32)
|
||||||
|
v11 += v15
|
||||||
|
v7 ^= v11
|
||||||
|
v7 = bits.RotateLeft64(v7, -24)
|
||||||
|
|
||||||
|
v0 += m[s[4]]
|
||||||
|
v0 += v4
|
||||||
|
v12 ^= v0
|
||||||
|
v12 = bits.RotateLeft64(v12, -16)
|
||||||
|
v8 += v12
|
||||||
|
v4 ^= v8
|
||||||
|
v4 = bits.RotateLeft64(v4, -63)
|
||||||
|
v1 += m[s[5]]
|
||||||
|
v1 += v5
|
||||||
|
v13 ^= v1
|
||||||
|
v13 = bits.RotateLeft64(v13, -16)
|
||||||
|
v9 += v13
|
||||||
|
v5 ^= v9
|
||||||
|
v5 = bits.RotateLeft64(v5, -63)
|
||||||
|
v2 += m[s[6]]
|
||||||
|
v2 += v6
|
||||||
|
v14 ^= v2
|
||||||
|
v14 = bits.RotateLeft64(v14, -16)
|
||||||
|
v10 += v14
|
||||||
|
v6 ^= v10
|
||||||
|
v6 = bits.RotateLeft64(v6, -63)
|
||||||
|
v3 += m[s[7]]
|
||||||
|
v3 += v7
|
||||||
|
v15 ^= v3
|
||||||
|
v15 = bits.RotateLeft64(v15, -16)
|
||||||
|
v11 += v15
|
||||||
|
v7 ^= v11
|
||||||
|
v7 = bits.RotateLeft64(v7, -63)
|
||||||
|
|
||||||
|
v0 += m[s[8]]
|
||||||
|
v0 += v5
|
||||||
|
v15 ^= v0
|
||||||
|
v15 = bits.RotateLeft64(v15, -32)
|
||||||
|
v10 += v15
|
||||||
|
v5 ^= v10
|
||||||
|
v5 = bits.RotateLeft64(v5, -24)
|
||||||
|
v1 += m[s[9]]
|
||||||
|
v1 += v6
|
||||||
|
v12 ^= v1
|
||||||
|
v12 = bits.RotateLeft64(v12, -32)
|
||||||
|
v11 += v12
|
||||||
|
v6 ^= v11
|
||||||
|
v6 = bits.RotateLeft64(v6, -24)
|
||||||
|
v2 += m[s[10]]
|
||||||
|
v2 += v7
|
||||||
|
v13 ^= v2
|
||||||
|
v13 = bits.RotateLeft64(v13, -32)
|
||||||
|
v8 += v13
|
||||||
|
v7 ^= v8
|
||||||
|
v7 = bits.RotateLeft64(v7, -24)
|
||||||
|
v3 += m[s[11]]
|
||||||
|
v3 += v4
|
||||||
|
v14 ^= v3
|
||||||
|
v14 = bits.RotateLeft64(v14, -32)
|
||||||
|
v9 += v14
|
||||||
|
v4 ^= v9
|
||||||
|
v4 = bits.RotateLeft64(v4, -24)
|
||||||
|
|
||||||
|
v0 += m[s[12]]
|
||||||
|
v0 += v5
|
||||||
|
v15 ^= v0
|
||||||
|
v15 = bits.RotateLeft64(v15, -16)
|
||||||
|
v10 += v15
|
||||||
|
v5 ^= v10
|
||||||
|
v5 = bits.RotateLeft64(v5, -63)
|
||||||
|
v1 += m[s[13]]
|
||||||
|
v1 += v6
|
||||||
|
v12 ^= v1
|
||||||
|
v12 = bits.RotateLeft64(v12, -16)
|
||||||
|
v11 += v12
|
||||||
|
v6 ^= v11
|
||||||
|
v6 = bits.RotateLeft64(v6, -63)
|
||||||
|
v2 += m[s[14]]
|
||||||
|
v2 += v7
|
||||||
|
v13 ^= v2
|
||||||
|
v13 = bits.RotateLeft64(v13, -16)
|
||||||
|
v8 += v13
|
||||||
|
v7 ^= v8
|
||||||
|
v7 = bits.RotateLeft64(v7, -63)
|
||||||
|
v3 += m[s[15]]
|
||||||
|
v3 += v4
|
||||||
|
v14 ^= v3
|
||||||
|
v14 = bits.RotateLeft64(v14, -16)
|
||||||
|
v9 += v14
|
||||||
|
v4 ^= v9
|
||||||
|
v4 = bits.RotateLeft64(v4, -63)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
h[0] ^= v0 ^ v8
|
||||||
|
h[1] ^= v1 ^ v9
|
||||||
|
h[2] ^= v2 ^ v10
|
||||||
|
h[3] ^= v3 ^ v11
|
||||||
|
h[4] ^= v4 ^ v12
|
||||||
|
h[5] ^= v5 ^ v13
|
||||||
|
h[6] ^= v6 ^ v14
|
||||||
|
h[7] ^= v7 ^ v15
|
||||||
|
}
|
||||||
|
c[0], c[1] = c0, c1
|
||||||
|
}
|
11
cli/v2/picocrypt/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go
generated
vendored
Normal file
11
cli/v2/picocrypt/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !amd64 || purego || !gc
|
||||||
|
|
||||||
|
package blake2b
|
||||||
|
|
||||||
|
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
|
||||||
|
hashBlocksGeneric(h, c, flag, blocks)
|
||||||
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package blake2b
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// XOF defines the interface to hash functions that
|
||||||
|
// support arbitrary-length output.
|
||||||
|
type XOF interface {
|
||||||
|
// Write absorbs more data into the hash's state. It panics if called
|
||||||
|
// after Read.
|
||||||
|
io.Writer
|
||||||
|
|
||||||
|
// Read reads more output from the hash. It returns io.EOF if the limit
|
||||||
|
// has been reached.
|
||||||
|
io.Reader
|
||||||
|
|
||||||
|
// Clone returns a copy of the XOF in its current state.
|
||||||
|
Clone() XOF
|
||||||
|
|
||||||
|
// Reset resets the XOF to its initial state.
|
||||||
|
Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// OutputLengthUnknown can be used as the size argument to NewXOF to indicate
|
||||||
|
// the length of the output is not known in advance.
|
||||||
|
const OutputLengthUnknown = 0
|
||||||
|
|
||||||
|
// magicUnknownOutputLength is a magic value for the output size that indicates
|
||||||
|
// an unknown number of output bytes.
|
||||||
|
const magicUnknownOutputLength = (1 << 32) - 1
|
||||||
|
|
||||||
|
// maxOutputLength is the absolute maximum number of bytes to produce when the
|
||||||
|
// number of output bytes is unknown.
|
||||||
|
const maxOutputLength = (1 << 32) * 64
|
||||||
|
|
||||||
|
// NewXOF creates a new variable-output-length hash. The hash either produce a
|
||||||
|
// known number of bytes (1 <= size < 2**32-1), or an unknown number of bytes
|
||||||
|
// (size == OutputLengthUnknown). In the latter case, an absolute limit of
|
||||||
|
// 256GiB applies.
|
||||||
|
//
|
||||||
|
// A non-nil key turns the hash into a MAC. The key must between
|
||||||
|
// zero and 32 bytes long.
|
||||||
|
func NewXOF(size uint32, key []byte) (XOF, error) {
|
||||||
|
if len(key) > Size {
|
||||||
|
return nil, errKeySize
|
||||||
|
}
|
||||||
|
if size == magicUnknownOutputLength {
|
||||||
|
// 2^32-1 indicates an unknown number of bytes and thus isn't a
|
||||||
|
// valid length.
|
||||||
|
return nil, errors.New("blake2b: XOF length too large")
|
||||||
|
}
|
||||||
|
if size == OutputLengthUnknown {
|
||||||
|
size = magicUnknownOutputLength
|
||||||
|
}
|
||||||
|
x := &xof{
|
||||||
|
d: digest{
|
||||||
|
size: Size,
|
||||||
|
keyLen: len(key),
|
||||||
|
},
|
||||||
|
length: size,
|
||||||
|
}
|
||||||
|
copy(x.d.key[:], key)
|
||||||
|
x.Reset()
|
||||||
|
return x, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type xof struct {
|
||||||
|
d digest
|
||||||
|
length uint32
|
||||||
|
remaining uint64
|
||||||
|
cfg, root, block [Size]byte
|
||||||
|
offset int
|
||||||
|
nodeOffset uint32
|
||||||
|
readMode bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *xof) Write(p []byte) (n int, err error) {
|
||||||
|
if x.readMode {
|
||||||
|
panic("blake2b: write to XOF after read")
|
||||||
|
}
|
||||||
|
return x.d.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *xof) Clone() XOF {
|
||||||
|
clone := *x
|
||||||
|
return &clone
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *xof) Reset() {
|
||||||
|
x.cfg[0] = byte(Size)
|
||||||
|
binary.LittleEndian.PutUint32(x.cfg[4:], uint32(Size)) // leaf length
|
||||||
|
binary.LittleEndian.PutUint32(x.cfg[12:], x.length) // XOF length
|
||||||
|
x.cfg[17] = byte(Size) // inner hash size
|
||||||
|
|
||||||
|
x.d.Reset()
|
||||||
|
x.d.h[1] ^= uint64(x.length) << 32
|
||||||
|
|
||||||
|
x.remaining = uint64(x.length)
|
||||||
|
if x.remaining == magicUnknownOutputLength {
|
||||||
|
x.remaining = maxOutputLength
|
||||||
|
}
|
||||||
|
x.offset, x.nodeOffset = 0, 0
|
||||||
|
x.readMode = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *xof) Read(p []byte) (n int, err error) {
|
||||||
|
if !x.readMode {
|
||||||
|
x.d.finalize(&x.root)
|
||||||
|
x.readMode = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if x.remaining == 0 {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
n = len(p)
|
||||||
|
if uint64(n) > x.remaining {
|
||||||
|
n = int(x.remaining)
|
||||||
|
p = p[:n]
|
||||||
|
}
|
||||||
|
|
||||||
|
if x.offset > 0 {
|
||||||
|
blockRemaining := Size - x.offset
|
||||||
|
if n < blockRemaining {
|
||||||
|
x.offset += copy(p, x.block[x.offset:])
|
||||||
|
x.remaining -= uint64(n)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
copy(p, x.block[x.offset:])
|
||||||
|
p = p[blockRemaining:]
|
||||||
|
x.offset = 0
|
||||||
|
x.remaining -= uint64(blockRemaining)
|
||||||
|
}
|
||||||
|
|
||||||
|
for len(p) >= Size {
|
||||||
|
binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
|
||||||
|
x.nodeOffset++
|
||||||
|
|
||||||
|
x.d.initConfig(&x.cfg)
|
||||||
|
x.d.Write(x.root[:])
|
||||||
|
x.d.finalize(&x.block)
|
||||||
|
|
||||||
|
copy(p, x.block[:])
|
||||||
|
p = p[Size:]
|
||||||
|
x.remaining -= uint64(Size)
|
||||||
|
}
|
||||||
|
|
||||||
|
if todo := len(p); todo > 0 {
|
||||||
|
if x.remaining < uint64(Size) {
|
||||||
|
x.cfg[0] = byte(x.remaining)
|
||||||
|
}
|
||||||
|
binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
|
||||||
|
x.nodeOffset++
|
||||||
|
|
||||||
|
x.d.initConfig(&x.cfg)
|
||||||
|
x.d.Write(x.root[:])
|
||||||
|
x.d.finalize(&x.block)
|
||||||
|
|
||||||
|
x.offset = copy(p, x.block[:todo])
|
||||||
|
x.remaining -= uint64(todo)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *digest) initConfig(cfg *[Size]byte) {
|
||||||
|
d.offset, d.c[0], d.c[1] = 0, 0, 0
|
||||||
|
for i := range d.h {
|
||||||
|
d.h[i] = iv[i] ^ binary.LittleEndian.Uint64(cfg[i*8:])
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package blake2b
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
newHash256 := func() hash.Hash {
|
||||||
|
h, _ := New256(nil)
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
newHash384 := func() hash.Hash {
|
||||||
|
h, _ := New384(nil)
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
newHash512 := func() hash.Hash {
|
||||||
|
h, _ := New512(nil)
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto.RegisterHash(crypto.BLAKE2b_256, newHash256)
|
||||||
|
crypto.RegisterHash(crypto.BLAKE2b_384, newHash384)
|
||||||
|
crypto.RegisterHash(crypto.BLAKE2b_512, newHash512)
|
||||||
|
}
|
16
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
generated
vendored
Normal file
16
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gc && !purego
|
||||||
|
|
||||||
|
package chacha20
|
||||||
|
|
||||||
|
const bufSize = 256
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
|
||||||
|
|
||||||
|
func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {
|
||||||
|
xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter)
|
||||||
|
}
|
307
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
generated
vendored
Normal file
307
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
generated
vendored
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gc && !purego
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
#define NUM_ROUNDS 10
|
||||||
|
|
||||||
|
// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
|
||||||
|
TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0
|
||||||
|
MOVD dst+0(FP), R1
|
||||||
|
MOVD src+24(FP), R2
|
||||||
|
MOVD src_len+32(FP), R3
|
||||||
|
MOVD key+48(FP), R4
|
||||||
|
MOVD nonce+56(FP), R6
|
||||||
|
MOVD counter+64(FP), R7
|
||||||
|
|
||||||
|
MOVD $·constants(SB), R10
|
||||||
|
MOVD $·incRotMatrix(SB), R11
|
||||||
|
|
||||||
|
MOVW (R7), R20
|
||||||
|
|
||||||
|
AND $~255, R3, R13
|
||||||
|
ADD R2, R13, R12 // R12 for block end
|
||||||
|
AND $255, R3, R13
|
||||||
|
loop:
|
||||||
|
MOVD $NUM_ROUNDS, R21
|
||||||
|
VLD1 (R11), [V30.S4, V31.S4]
|
||||||
|
|
||||||
|
// load contants
|
||||||
|
// VLD4R (R10), [V0.S4, V1.S4, V2.S4, V3.S4]
|
||||||
|
WORD $0x4D60E940
|
||||||
|
|
||||||
|
// load keys
|
||||||
|
// VLD4R 16(R4), [V4.S4, V5.S4, V6.S4, V7.S4]
|
||||||
|
WORD $0x4DFFE884
|
||||||
|
// VLD4R 16(R4), [V8.S4, V9.S4, V10.S4, V11.S4]
|
||||||
|
WORD $0x4DFFE888
|
||||||
|
SUB $32, R4
|
||||||
|
|
||||||
|
// load counter + nonce
|
||||||
|
// VLD1R (R7), [V12.S4]
|
||||||
|
WORD $0x4D40C8EC
|
||||||
|
|
||||||
|
// VLD3R (R6), [V13.S4, V14.S4, V15.S4]
|
||||||
|
WORD $0x4D40E8CD
|
||||||
|
|
||||||
|
// update counter
|
||||||
|
VADD V30.S4, V12.S4, V12.S4
|
||||||
|
|
||||||
|
chacha:
|
||||||
|
// V0..V3 += V4..V7
|
||||||
|
// V12..V15 <<<= ((V12..V15 XOR V0..V3), 16)
|
||||||
|
VADD V0.S4, V4.S4, V0.S4
|
||||||
|
VADD V1.S4, V5.S4, V1.S4
|
||||||
|
VADD V2.S4, V6.S4, V2.S4
|
||||||
|
VADD V3.S4, V7.S4, V3.S4
|
||||||
|
VEOR V12.B16, V0.B16, V12.B16
|
||||||
|
VEOR V13.B16, V1.B16, V13.B16
|
||||||
|
VEOR V14.B16, V2.B16, V14.B16
|
||||||
|
VEOR V15.B16, V3.B16, V15.B16
|
||||||
|
VREV32 V12.H8, V12.H8
|
||||||
|
VREV32 V13.H8, V13.H8
|
||||||
|
VREV32 V14.H8, V14.H8
|
||||||
|
VREV32 V15.H8, V15.H8
|
||||||
|
// V8..V11 += V12..V15
|
||||||
|
// V4..V7 <<<= ((V4..V7 XOR V8..V11), 12)
|
||||||
|
VADD V8.S4, V12.S4, V8.S4
|
||||||
|
VADD V9.S4, V13.S4, V9.S4
|
||||||
|
VADD V10.S4, V14.S4, V10.S4
|
||||||
|
VADD V11.S4, V15.S4, V11.S4
|
||||||
|
VEOR V8.B16, V4.B16, V16.B16
|
||||||
|
VEOR V9.B16, V5.B16, V17.B16
|
||||||
|
VEOR V10.B16, V6.B16, V18.B16
|
||||||
|
VEOR V11.B16, V7.B16, V19.B16
|
||||||
|
VSHL $12, V16.S4, V4.S4
|
||||||
|
VSHL $12, V17.S4, V5.S4
|
||||||
|
VSHL $12, V18.S4, V6.S4
|
||||||
|
VSHL $12, V19.S4, V7.S4
|
||||||
|
VSRI $20, V16.S4, V4.S4
|
||||||
|
VSRI $20, V17.S4, V5.S4
|
||||||
|
VSRI $20, V18.S4, V6.S4
|
||||||
|
VSRI $20, V19.S4, V7.S4
|
||||||
|
|
||||||
|
// V0..V3 += V4..V7
|
||||||
|
// V12..V15 <<<= ((V12..V15 XOR V0..V3), 8)
|
||||||
|
VADD V0.S4, V4.S4, V0.S4
|
||||||
|
VADD V1.S4, V5.S4, V1.S4
|
||||||
|
VADD V2.S4, V6.S4, V2.S4
|
||||||
|
VADD V3.S4, V7.S4, V3.S4
|
||||||
|
VEOR V12.B16, V0.B16, V12.B16
|
||||||
|
VEOR V13.B16, V1.B16, V13.B16
|
||||||
|
VEOR V14.B16, V2.B16, V14.B16
|
||||||
|
VEOR V15.B16, V3.B16, V15.B16
|
||||||
|
VTBL V31.B16, [V12.B16], V12.B16
|
||||||
|
VTBL V31.B16, [V13.B16], V13.B16
|
||||||
|
VTBL V31.B16, [V14.B16], V14.B16
|
||||||
|
VTBL V31.B16, [V15.B16], V15.B16
|
||||||
|
|
||||||
|
// V8..V11 += V12..V15
|
||||||
|
// V4..V7 <<<= ((V4..V7 XOR V8..V11), 7)
|
||||||
|
VADD V12.S4, V8.S4, V8.S4
|
||||||
|
VADD V13.S4, V9.S4, V9.S4
|
||||||
|
VADD V14.S4, V10.S4, V10.S4
|
||||||
|
VADD V15.S4, V11.S4, V11.S4
|
||||||
|
VEOR V8.B16, V4.B16, V16.B16
|
||||||
|
VEOR V9.B16, V5.B16, V17.B16
|
||||||
|
VEOR V10.B16, V6.B16, V18.B16
|
||||||
|
VEOR V11.B16, V7.B16, V19.B16
|
||||||
|
VSHL $7, V16.S4, V4.S4
|
||||||
|
VSHL $7, V17.S4, V5.S4
|
||||||
|
VSHL $7, V18.S4, V6.S4
|
||||||
|
VSHL $7, V19.S4, V7.S4
|
||||||
|
VSRI $25, V16.S4, V4.S4
|
||||||
|
VSRI $25, V17.S4, V5.S4
|
||||||
|
VSRI $25, V18.S4, V6.S4
|
||||||
|
VSRI $25, V19.S4, V7.S4
|
||||||
|
|
||||||
|
// V0..V3 += V5..V7, V4
|
||||||
|
// V15,V12-V14 <<<= ((V15,V12-V14 XOR V0..V3), 16)
|
||||||
|
VADD V0.S4, V5.S4, V0.S4
|
||||||
|
VADD V1.S4, V6.S4, V1.S4
|
||||||
|
VADD V2.S4, V7.S4, V2.S4
|
||||||
|
VADD V3.S4, V4.S4, V3.S4
|
||||||
|
VEOR V15.B16, V0.B16, V15.B16
|
||||||
|
VEOR V12.B16, V1.B16, V12.B16
|
||||||
|
VEOR V13.B16, V2.B16, V13.B16
|
||||||
|
VEOR V14.B16, V3.B16, V14.B16
|
||||||
|
VREV32 V12.H8, V12.H8
|
||||||
|
VREV32 V13.H8, V13.H8
|
||||||
|
VREV32 V14.H8, V14.H8
|
||||||
|
VREV32 V15.H8, V15.H8
|
||||||
|
|
||||||
|
// V10 += V15; V5 <<<= ((V10 XOR V5), 12)
|
||||||
|
// ...
|
||||||
|
VADD V15.S4, V10.S4, V10.S4
|
||||||
|
VADD V12.S4, V11.S4, V11.S4
|
||||||
|
VADD V13.S4, V8.S4, V8.S4
|
||||||
|
VADD V14.S4, V9.S4, V9.S4
|
||||||
|
VEOR V10.B16, V5.B16, V16.B16
|
||||||
|
VEOR V11.B16, V6.B16, V17.B16
|
||||||
|
VEOR V8.B16, V7.B16, V18.B16
|
||||||
|
VEOR V9.B16, V4.B16, V19.B16
|
||||||
|
VSHL $12, V16.S4, V5.S4
|
||||||
|
VSHL $12, V17.S4, V6.S4
|
||||||
|
VSHL $12, V18.S4, V7.S4
|
||||||
|
VSHL $12, V19.S4, V4.S4
|
||||||
|
VSRI $20, V16.S4, V5.S4
|
||||||
|
VSRI $20, V17.S4, V6.S4
|
||||||
|
VSRI $20, V18.S4, V7.S4
|
||||||
|
VSRI $20, V19.S4, V4.S4
|
||||||
|
|
||||||
|
// V0 += V5; V15 <<<= ((V0 XOR V15), 8)
|
||||||
|
// ...
|
||||||
|
VADD V5.S4, V0.S4, V0.S4
|
||||||
|
VADD V6.S4, V1.S4, V1.S4
|
||||||
|
VADD V7.S4, V2.S4, V2.S4
|
||||||
|
VADD V4.S4, V3.S4, V3.S4
|
||||||
|
VEOR V0.B16, V15.B16, V15.B16
|
||||||
|
VEOR V1.B16, V12.B16, V12.B16
|
||||||
|
VEOR V2.B16, V13.B16, V13.B16
|
||||||
|
VEOR V3.B16, V14.B16, V14.B16
|
||||||
|
VTBL V31.B16, [V12.B16], V12.B16
|
||||||
|
VTBL V31.B16, [V13.B16], V13.B16
|
||||||
|
VTBL V31.B16, [V14.B16], V14.B16
|
||||||
|
VTBL V31.B16, [V15.B16], V15.B16
|
||||||
|
|
||||||
|
// V10 += V15; V5 <<<= ((V10 XOR V5), 7)
|
||||||
|
// ...
|
||||||
|
VADD V15.S4, V10.S4, V10.S4
|
||||||
|
VADD V12.S4, V11.S4, V11.S4
|
||||||
|
VADD V13.S4, V8.S4, V8.S4
|
||||||
|
VADD V14.S4, V9.S4, V9.S4
|
||||||
|
VEOR V10.B16, V5.B16, V16.B16
|
||||||
|
VEOR V11.B16, V6.B16, V17.B16
|
||||||
|
VEOR V8.B16, V7.B16, V18.B16
|
||||||
|
VEOR V9.B16, V4.B16, V19.B16
|
||||||
|
VSHL $7, V16.S4, V5.S4
|
||||||
|
VSHL $7, V17.S4, V6.S4
|
||||||
|
VSHL $7, V18.S4, V7.S4
|
||||||
|
VSHL $7, V19.S4, V4.S4
|
||||||
|
VSRI $25, V16.S4, V5.S4
|
||||||
|
VSRI $25, V17.S4, V6.S4
|
||||||
|
VSRI $25, V18.S4, V7.S4
|
||||||
|
VSRI $25, V19.S4, V4.S4
|
||||||
|
|
||||||
|
SUB $1, R21
|
||||||
|
CBNZ R21, chacha
|
||||||
|
|
||||||
|
// VLD4R (R10), [V16.S4, V17.S4, V18.S4, V19.S4]
|
||||||
|
WORD $0x4D60E950
|
||||||
|
|
||||||
|
// VLD4R 16(R4), [V20.S4, V21.S4, V22.S4, V23.S4]
|
||||||
|
WORD $0x4DFFE894
|
||||||
|
VADD V30.S4, V12.S4, V12.S4
|
||||||
|
VADD V16.S4, V0.S4, V0.S4
|
||||||
|
VADD V17.S4, V1.S4, V1.S4
|
||||||
|
VADD V18.S4, V2.S4, V2.S4
|
||||||
|
VADD V19.S4, V3.S4, V3.S4
|
||||||
|
// VLD4R 16(R4), [V24.S4, V25.S4, V26.S4, V27.S4]
|
||||||
|
WORD $0x4DFFE898
|
||||||
|
// restore R4
|
||||||
|
SUB $32, R4
|
||||||
|
|
||||||
|
// load counter + nonce
|
||||||
|
// VLD1R (R7), [V28.S4]
|
||||||
|
WORD $0x4D40C8FC
|
||||||
|
// VLD3R (R6), [V29.S4, V30.S4, V31.S4]
|
||||||
|
WORD $0x4D40E8DD
|
||||||
|
|
||||||
|
VADD V20.S4, V4.S4, V4.S4
|
||||||
|
VADD V21.S4, V5.S4, V5.S4
|
||||||
|
VADD V22.S4, V6.S4, V6.S4
|
||||||
|
VADD V23.S4, V7.S4, V7.S4
|
||||||
|
VADD V24.S4, V8.S4, V8.S4
|
||||||
|
VADD V25.S4, V9.S4, V9.S4
|
||||||
|
VADD V26.S4, V10.S4, V10.S4
|
||||||
|
VADD V27.S4, V11.S4, V11.S4
|
||||||
|
VADD V28.S4, V12.S4, V12.S4
|
||||||
|
VADD V29.S4, V13.S4, V13.S4
|
||||||
|
VADD V30.S4, V14.S4, V14.S4
|
||||||
|
VADD V31.S4, V15.S4, V15.S4
|
||||||
|
|
||||||
|
VZIP1 V1.S4, V0.S4, V16.S4
|
||||||
|
VZIP2 V1.S4, V0.S4, V17.S4
|
||||||
|
VZIP1 V3.S4, V2.S4, V18.S4
|
||||||
|
VZIP2 V3.S4, V2.S4, V19.S4
|
||||||
|
VZIP1 V5.S4, V4.S4, V20.S4
|
||||||
|
VZIP2 V5.S4, V4.S4, V21.S4
|
||||||
|
VZIP1 V7.S4, V6.S4, V22.S4
|
||||||
|
VZIP2 V7.S4, V6.S4, V23.S4
|
||||||
|
VZIP1 V9.S4, V8.S4, V24.S4
|
||||||
|
VZIP2 V9.S4, V8.S4, V25.S4
|
||||||
|
VZIP1 V11.S4, V10.S4, V26.S4
|
||||||
|
VZIP2 V11.S4, V10.S4, V27.S4
|
||||||
|
VZIP1 V13.S4, V12.S4, V28.S4
|
||||||
|
VZIP2 V13.S4, V12.S4, V29.S4
|
||||||
|
VZIP1 V15.S4, V14.S4, V30.S4
|
||||||
|
VZIP2 V15.S4, V14.S4, V31.S4
|
||||||
|
VZIP1 V18.D2, V16.D2, V0.D2
|
||||||
|
VZIP2 V18.D2, V16.D2, V4.D2
|
||||||
|
VZIP1 V19.D2, V17.D2, V8.D2
|
||||||
|
VZIP2 V19.D2, V17.D2, V12.D2
|
||||||
|
VLD1.P 64(R2), [V16.B16, V17.B16, V18.B16, V19.B16]
|
||||||
|
|
||||||
|
VZIP1 V22.D2, V20.D2, V1.D2
|
||||||
|
VZIP2 V22.D2, V20.D2, V5.D2
|
||||||
|
VZIP1 V23.D2, V21.D2, V9.D2
|
||||||
|
VZIP2 V23.D2, V21.D2, V13.D2
|
||||||
|
VLD1.P 64(R2), [V20.B16, V21.B16, V22.B16, V23.B16]
|
||||||
|
VZIP1 V26.D2, V24.D2, V2.D2
|
||||||
|
VZIP2 V26.D2, V24.D2, V6.D2
|
||||||
|
VZIP1 V27.D2, V25.D2, V10.D2
|
||||||
|
VZIP2 V27.D2, V25.D2, V14.D2
|
||||||
|
VLD1.P 64(R2), [V24.B16, V25.B16, V26.B16, V27.B16]
|
||||||
|
VZIP1 V30.D2, V28.D2, V3.D2
|
||||||
|
VZIP2 V30.D2, V28.D2, V7.D2
|
||||||
|
VZIP1 V31.D2, V29.D2, V11.D2
|
||||||
|
VZIP2 V31.D2, V29.D2, V15.D2
|
||||||
|
VLD1.P 64(R2), [V28.B16, V29.B16, V30.B16, V31.B16]
|
||||||
|
VEOR V0.B16, V16.B16, V16.B16
|
||||||
|
VEOR V1.B16, V17.B16, V17.B16
|
||||||
|
VEOR V2.B16, V18.B16, V18.B16
|
||||||
|
VEOR V3.B16, V19.B16, V19.B16
|
||||||
|
VST1.P [V16.B16, V17.B16, V18.B16, V19.B16], 64(R1)
|
||||||
|
VEOR V4.B16, V20.B16, V20.B16
|
||||||
|
VEOR V5.B16, V21.B16, V21.B16
|
||||||
|
VEOR V6.B16, V22.B16, V22.B16
|
||||||
|
VEOR V7.B16, V23.B16, V23.B16
|
||||||
|
VST1.P [V20.B16, V21.B16, V22.B16, V23.B16], 64(R1)
|
||||||
|
VEOR V8.B16, V24.B16, V24.B16
|
||||||
|
VEOR V9.B16, V25.B16, V25.B16
|
||||||
|
VEOR V10.B16, V26.B16, V26.B16
|
||||||
|
VEOR V11.B16, V27.B16, V27.B16
|
||||||
|
VST1.P [V24.B16, V25.B16, V26.B16, V27.B16], 64(R1)
|
||||||
|
VEOR V12.B16, V28.B16, V28.B16
|
||||||
|
VEOR V13.B16, V29.B16, V29.B16
|
||||||
|
VEOR V14.B16, V30.B16, V30.B16
|
||||||
|
VEOR V15.B16, V31.B16, V31.B16
|
||||||
|
VST1.P [V28.B16, V29.B16, V30.B16, V31.B16], 64(R1)
|
||||||
|
|
||||||
|
ADD $4, R20
|
||||||
|
MOVW R20, (R7) // update counter
|
||||||
|
|
||||||
|
CMP R2, R12
|
||||||
|
BGT loop
|
||||||
|
|
||||||
|
RET
|
||||||
|
|
||||||
|
|
||||||
|
DATA ·constants+0x00(SB)/4, $0x61707865
|
||||||
|
DATA ·constants+0x04(SB)/4, $0x3320646e
|
||||||
|
DATA ·constants+0x08(SB)/4, $0x79622d32
|
||||||
|
DATA ·constants+0x0c(SB)/4, $0x6b206574
|
||||||
|
GLOBL ·constants(SB), NOPTR|RODATA, $32
|
||||||
|
|
||||||
|
DATA ·incRotMatrix+0x00(SB)/4, $0x00000000
|
||||||
|
DATA ·incRotMatrix+0x04(SB)/4, $0x00000001
|
||||||
|
DATA ·incRotMatrix+0x08(SB)/4, $0x00000002
|
||||||
|
DATA ·incRotMatrix+0x0c(SB)/4, $0x00000003
|
||||||
|
DATA ·incRotMatrix+0x10(SB)/4, $0x02010003
|
||||||
|
DATA ·incRotMatrix+0x14(SB)/4, $0x06050407
|
||||||
|
DATA ·incRotMatrix+0x18(SB)/4, $0x0A09080B
|
||||||
|
DATA ·incRotMatrix+0x1c(SB)/4, $0x0E0D0C0F
|
||||||
|
GLOBL ·incRotMatrix(SB), NOPTR|RODATA, $32
|
398
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_generic.go
generated
vendored
Normal file
398
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_generic.go
generated
vendored
Normal file
|
@ -0,0 +1,398 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package chacha20 implements the ChaCha20 and XChaCha20 encryption algorithms
|
||||||
|
// as specified in RFC 8439 and draft-irtf-cfrg-xchacha-01.
|
||||||
|
package chacha20
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/cipher"
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"math/bits"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/internal/alias"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// KeySize is the size of the key used by this cipher, in bytes.
|
||||||
|
KeySize = 32
|
||||||
|
|
||||||
|
// NonceSize is the size of the nonce used with the standard variant of this
|
||||||
|
// cipher, in bytes.
|
||||||
|
//
|
||||||
|
// Note that this is too short to be safely generated at random if the same
|
||||||
|
// key is reused more than 2³² times.
|
||||||
|
NonceSize = 12
|
||||||
|
|
||||||
|
// NonceSizeX is the size of the nonce used with the XChaCha20 variant of
|
||||||
|
// this cipher, in bytes.
|
||||||
|
NonceSizeX = 24
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cipher is a stateful instance of ChaCha20 or XChaCha20 using a particular key
|
||||||
|
// and nonce. A *Cipher implements the cipher.Stream interface.
|
||||||
|
type Cipher struct {
|
||||||
|
// The ChaCha20 state is 16 words: 4 constant, 8 of key, 1 of counter
|
||||||
|
// (incremented after each block), and 3 of nonce.
|
||||||
|
key [8]uint32
|
||||||
|
counter uint32
|
||||||
|
nonce [3]uint32
|
||||||
|
|
||||||
|
// The last len bytes of buf are leftover key stream bytes from the previous
|
||||||
|
// XORKeyStream invocation. The size of buf depends on how many blocks are
|
||||||
|
// computed at a time by xorKeyStreamBlocks.
|
||||||
|
buf [bufSize]byte
|
||||||
|
len int
|
||||||
|
|
||||||
|
// overflow is set when the counter overflowed, no more blocks can be
|
||||||
|
// generated, and the next XORKeyStream call should panic.
|
||||||
|
overflow bool
|
||||||
|
|
||||||
|
// The counter-independent results of the first round are cached after they
|
||||||
|
// are computed the first time.
|
||||||
|
precompDone bool
|
||||||
|
p1, p5, p9, p13 uint32
|
||||||
|
p2, p6, p10, p14 uint32
|
||||||
|
p3, p7, p11, p15 uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ cipher.Stream = (*Cipher)(nil)
|
||||||
|
|
||||||
|
// NewUnauthenticatedCipher creates a new ChaCha20 stream cipher with the given
|
||||||
|
// 32 bytes key and a 12 or 24 bytes nonce. If a nonce of 24 bytes is provided,
|
||||||
|
// the XChaCha20 construction will be used. It returns an error if key or nonce
|
||||||
|
// have any other length.
|
||||||
|
//
|
||||||
|
// Note that ChaCha20, like all stream ciphers, is not authenticated and allows
|
||||||
|
// attackers to silently tamper with the plaintext. For this reason, it is more
|
||||||
|
// appropriate as a building block than as a standalone encryption mechanism.
|
||||||
|
// Instead, consider using package golang.org/x/crypto/chacha20poly1305.
|
||||||
|
func NewUnauthenticatedCipher(key, nonce []byte) (*Cipher, error) {
|
||||||
|
// This function is split into a wrapper so that the Cipher allocation will
|
||||||
|
// be inlined, and depending on how the caller uses the return value, won't
|
||||||
|
// escape to the heap.
|
||||||
|
c := &Cipher{}
|
||||||
|
return newUnauthenticatedCipher(c, key, nonce)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newUnauthenticatedCipher(c *Cipher, key, nonce []byte) (*Cipher, error) {
|
||||||
|
if len(key) != KeySize {
|
||||||
|
return nil, errors.New("chacha20: wrong key size")
|
||||||
|
}
|
||||||
|
if len(nonce) == NonceSizeX {
|
||||||
|
// XChaCha20 uses the ChaCha20 core to mix 16 bytes of the nonce into a
|
||||||
|
// derived key, allowing it to operate on a nonce of 24 bytes. See
|
||||||
|
// draft-irtf-cfrg-xchacha-01, Section 2.3.
|
||||||
|
key, _ = HChaCha20(key, nonce[0:16])
|
||||||
|
cNonce := make([]byte, NonceSize)
|
||||||
|
copy(cNonce[4:12], nonce[16:24])
|
||||||
|
nonce = cNonce
|
||||||
|
} else if len(nonce) != NonceSize {
|
||||||
|
return nil, errors.New("chacha20: wrong nonce size")
|
||||||
|
}
|
||||||
|
|
||||||
|
key, nonce = key[:KeySize], nonce[:NonceSize] // bounds check elimination hint
|
||||||
|
c.key = [8]uint32{
|
||||||
|
binary.LittleEndian.Uint32(key[0:4]),
|
||||||
|
binary.LittleEndian.Uint32(key[4:8]),
|
||||||
|
binary.LittleEndian.Uint32(key[8:12]),
|
||||||
|
binary.LittleEndian.Uint32(key[12:16]),
|
||||||
|
binary.LittleEndian.Uint32(key[16:20]),
|
||||||
|
binary.LittleEndian.Uint32(key[20:24]),
|
||||||
|
binary.LittleEndian.Uint32(key[24:28]),
|
||||||
|
binary.LittleEndian.Uint32(key[28:32]),
|
||||||
|
}
|
||||||
|
c.nonce = [3]uint32{
|
||||||
|
binary.LittleEndian.Uint32(nonce[0:4]),
|
||||||
|
binary.LittleEndian.Uint32(nonce[4:8]),
|
||||||
|
binary.LittleEndian.Uint32(nonce[8:12]),
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// The constant first 4 words of the ChaCha20 state.
|
||||||
|
const (
|
||||||
|
j0 uint32 = 0x61707865 // expa
|
||||||
|
j1 uint32 = 0x3320646e // nd 3
|
||||||
|
j2 uint32 = 0x79622d32 // 2-by
|
||||||
|
j3 uint32 = 0x6b206574 // te k
|
||||||
|
)
|
||||||
|
|
||||||
|
const blockSize = 64
|
||||||
|
|
||||||
|
// quarterRound is the core of ChaCha20. It shuffles the bits of 4 state words.
|
||||||
|
// It's executed 4 times for each of the 20 ChaCha20 rounds, operating on all 16
|
||||||
|
// words each round, in columnar or diagonal groups of 4 at a time.
|
||||||
|
func quarterRound(a, b, c, d uint32) (uint32, uint32, uint32, uint32) {
|
||||||
|
a += b
|
||||||
|
d ^= a
|
||||||
|
d = bits.RotateLeft32(d, 16)
|
||||||
|
c += d
|
||||||
|
b ^= c
|
||||||
|
b = bits.RotateLeft32(b, 12)
|
||||||
|
a += b
|
||||||
|
d ^= a
|
||||||
|
d = bits.RotateLeft32(d, 8)
|
||||||
|
c += d
|
||||||
|
b ^= c
|
||||||
|
b = bits.RotateLeft32(b, 7)
|
||||||
|
return a, b, c, d
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCounter sets the Cipher counter. The next invocation of XORKeyStream will
|
||||||
|
// behave as if (64 * counter) bytes had been encrypted so far.
|
||||||
|
//
|
||||||
|
// To prevent accidental counter reuse, SetCounter panics if counter is less
|
||||||
|
// than the current value.
|
||||||
|
//
|
||||||
|
// Note that the execution time of XORKeyStream is not independent of the
|
||||||
|
// counter value.
|
||||||
|
func (s *Cipher) SetCounter(counter uint32) {
|
||||||
|
// Internally, s may buffer multiple blocks, which complicates this
|
||||||
|
// implementation slightly. When checking whether the counter has rolled
|
||||||
|
// back, we must use both s.counter and s.len to determine how many blocks
|
||||||
|
// we have already output.
|
||||||
|
outputCounter := s.counter - uint32(s.len)/blockSize
|
||||||
|
if s.overflow || counter < outputCounter {
|
||||||
|
panic("chacha20: SetCounter attempted to rollback counter")
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the general case, we set the new counter value and reset s.len to 0,
|
||||||
|
// causing the next call to XORKeyStream to refill the buffer. However, if
|
||||||
|
// we're advancing within the existing buffer, we can save work by simply
|
||||||
|
// setting s.len.
|
||||||
|
if counter < s.counter {
|
||||||
|
s.len = int(s.counter-counter) * blockSize
|
||||||
|
} else {
|
||||||
|
s.counter = counter
|
||||||
|
s.len = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XORKeyStream XORs each byte in the given slice with a byte from the
|
||||||
|
// cipher's key stream. Dst and src must overlap entirely or not at all.
|
||||||
|
//
|
||||||
|
// If len(dst) < len(src), XORKeyStream will panic. It is acceptable
|
||||||
|
// to pass a dst bigger than src, and in that case, XORKeyStream will
|
||||||
|
// only update dst[:len(src)] and will not touch the rest of dst.
|
||||||
|
//
|
||||||
|
// Multiple calls to XORKeyStream behave as if the concatenation of
|
||||||
|
// the src buffers was passed in a single run. That is, Cipher
|
||||||
|
// maintains state and does not reset at each XORKeyStream call.
|
||||||
|
func (s *Cipher) XORKeyStream(dst, src []byte) {
|
||||||
|
if len(src) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(dst) < len(src) {
|
||||||
|
panic("chacha20: output smaller than input")
|
||||||
|
}
|
||||||
|
dst = dst[:len(src)]
|
||||||
|
if alias.InexactOverlap(dst, src) {
|
||||||
|
panic("chacha20: invalid buffer overlap")
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, drain any remaining key stream from a previous XORKeyStream.
|
||||||
|
if s.len != 0 {
|
||||||
|
keyStream := s.buf[bufSize-s.len:]
|
||||||
|
if len(src) < len(keyStream) {
|
||||||
|
keyStream = keyStream[:len(src)]
|
||||||
|
}
|
||||||
|
_ = src[len(keyStream)-1] // bounds check elimination hint
|
||||||
|
for i, b := range keyStream {
|
||||||
|
dst[i] = src[i] ^ b
|
||||||
|
}
|
||||||
|
s.len -= len(keyStream)
|
||||||
|
dst, src = dst[len(keyStream):], src[len(keyStream):]
|
||||||
|
}
|
||||||
|
if len(src) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we'd need to let the counter overflow and keep generating output,
|
||||||
|
// panic immediately. If instead we'd only reach the last block, remember
|
||||||
|
// not to generate any more output after the buffer is drained.
|
||||||
|
numBlocks := (uint64(len(src)) + blockSize - 1) / blockSize
|
||||||
|
if s.overflow || uint64(s.counter)+numBlocks > 1<<32 {
|
||||||
|
panic("chacha20: counter overflow")
|
||||||
|
} else if uint64(s.counter)+numBlocks == 1<<32 {
|
||||||
|
s.overflow = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// xorKeyStreamBlocks implementations expect input lengths that are a
|
||||||
|
// multiple of bufSize. Platform-specific ones process multiple blocks at a
|
||||||
|
// time, so have bufSizes that are a multiple of blockSize.
|
||||||
|
|
||||||
|
full := len(src) - len(src)%bufSize
|
||||||
|
if full > 0 {
|
||||||
|
s.xorKeyStreamBlocks(dst[:full], src[:full])
|
||||||
|
}
|
||||||
|
dst, src = dst[full:], src[full:]
|
||||||
|
|
||||||
|
// If using a multi-block xorKeyStreamBlocks would overflow, use the generic
|
||||||
|
// one that does one block at a time.
|
||||||
|
const blocksPerBuf = bufSize / blockSize
|
||||||
|
if uint64(s.counter)+blocksPerBuf > 1<<32 {
|
||||||
|
s.buf = [bufSize]byte{}
|
||||||
|
numBlocks := (len(src) + blockSize - 1) / blockSize
|
||||||
|
buf := s.buf[bufSize-numBlocks*blockSize:]
|
||||||
|
copy(buf, src)
|
||||||
|
s.xorKeyStreamBlocksGeneric(buf, buf)
|
||||||
|
s.len = len(buf) - copy(dst, buf)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have a partial (multi-)block, pad it for xorKeyStreamBlocks, and
|
||||||
|
// keep the leftover keystream for the next XORKeyStream invocation.
|
||||||
|
if len(src) > 0 {
|
||||||
|
s.buf = [bufSize]byte{}
|
||||||
|
copy(s.buf[:], src)
|
||||||
|
s.xorKeyStreamBlocks(s.buf[:], s.buf[:])
|
||||||
|
s.len = bufSize - copy(dst, s.buf[:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Cipher) xorKeyStreamBlocksGeneric(dst, src []byte) {
|
||||||
|
if len(dst) != len(src) || len(dst)%blockSize != 0 {
|
||||||
|
panic("chacha20: internal error: wrong dst and/or src length")
|
||||||
|
}
|
||||||
|
|
||||||
|
// To generate each block of key stream, the initial cipher state
|
||||||
|
// (represented below) is passed through 20 rounds of shuffling,
|
||||||
|
// alternatively applying quarterRounds by columns (like 1, 5, 9, 13)
|
||||||
|
// or by diagonals (like 1, 6, 11, 12).
|
||||||
|
//
|
||||||
|
// 0:cccccccc 1:cccccccc 2:cccccccc 3:cccccccc
|
||||||
|
// 4:kkkkkkkk 5:kkkkkkkk 6:kkkkkkkk 7:kkkkkkkk
|
||||||
|
// 8:kkkkkkkk 9:kkkkkkkk 10:kkkkkkkk 11:kkkkkkkk
|
||||||
|
// 12:bbbbbbbb 13:nnnnnnnn 14:nnnnnnnn 15:nnnnnnnn
|
||||||
|
//
|
||||||
|
// c=constant k=key b=blockcount n=nonce
|
||||||
|
var (
|
||||||
|
c0, c1, c2, c3 = j0, j1, j2, j3
|
||||||
|
c4, c5, c6, c7 = s.key[0], s.key[1], s.key[2], s.key[3]
|
||||||
|
c8, c9, c10, c11 = s.key[4], s.key[5], s.key[6], s.key[7]
|
||||||
|
_, c13, c14, c15 = s.counter, s.nonce[0], s.nonce[1], s.nonce[2]
|
||||||
|
)
|
||||||
|
|
||||||
|
// Three quarters of the first round don't depend on the counter, so we can
|
||||||
|
// calculate them here, and reuse them for multiple blocks in the loop, and
|
||||||
|
// for future XORKeyStream invocations.
|
||||||
|
if !s.precompDone {
|
||||||
|
s.p1, s.p5, s.p9, s.p13 = quarterRound(c1, c5, c9, c13)
|
||||||
|
s.p2, s.p6, s.p10, s.p14 = quarterRound(c2, c6, c10, c14)
|
||||||
|
s.p3, s.p7, s.p11, s.p15 = quarterRound(c3, c7, c11, c15)
|
||||||
|
s.precompDone = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// A condition of len(src) > 0 would be sufficient, but this also
|
||||||
|
// acts as a bounds check elimination hint.
|
||||||
|
for len(src) >= 64 && len(dst) >= 64 {
|
||||||
|
// The remainder of the first column round.
|
||||||
|
fcr0, fcr4, fcr8, fcr12 := quarterRound(c0, c4, c8, s.counter)
|
||||||
|
|
||||||
|
// The second diagonal round.
|
||||||
|
x0, x5, x10, x15 := quarterRound(fcr0, s.p5, s.p10, s.p15)
|
||||||
|
x1, x6, x11, x12 := quarterRound(s.p1, s.p6, s.p11, fcr12)
|
||||||
|
x2, x7, x8, x13 := quarterRound(s.p2, s.p7, fcr8, s.p13)
|
||||||
|
x3, x4, x9, x14 := quarterRound(s.p3, fcr4, s.p9, s.p14)
|
||||||
|
|
||||||
|
// The remaining 18 rounds.
|
||||||
|
for i := 0; i < 9; i++ {
|
||||||
|
// Column round.
|
||||||
|
x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12)
|
||||||
|
x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13)
|
||||||
|
x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14)
|
||||||
|
x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15)
|
||||||
|
|
||||||
|
// Diagonal round.
|
||||||
|
x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15)
|
||||||
|
x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12)
|
||||||
|
x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13)
|
||||||
|
x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add back the initial state to generate the key stream, then
|
||||||
|
// XOR the key stream with the source and write out the result.
|
||||||
|
addXor(dst[0:4], src[0:4], x0, c0)
|
||||||
|
addXor(dst[4:8], src[4:8], x1, c1)
|
||||||
|
addXor(dst[8:12], src[8:12], x2, c2)
|
||||||
|
addXor(dst[12:16], src[12:16], x3, c3)
|
||||||
|
addXor(dst[16:20], src[16:20], x4, c4)
|
||||||
|
addXor(dst[20:24], src[20:24], x5, c5)
|
||||||
|
addXor(dst[24:28], src[24:28], x6, c6)
|
||||||
|
addXor(dst[28:32], src[28:32], x7, c7)
|
||||||
|
addXor(dst[32:36], src[32:36], x8, c8)
|
||||||
|
addXor(dst[36:40], src[36:40], x9, c9)
|
||||||
|
addXor(dst[40:44], src[40:44], x10, c10)
|
||||||
|
addXor(dst[44:48], src[44:48], x11, c11)
|
||||||
|
addXor(dst[48:52], src[48:52], x12, s.counter)
|
||||||
|
addXor(dst[52:56], src[52:56], x13, c13)
|
||||||
|
addXor(dst[56:60], src[56:60], x14, c14)
|
||||||
|
addXor(dst[60:64], src[60:64], x15, c15)
|
||||||
|
|
||||||
|
s.counter += 1
|
||||||
|
|
||||||
|
src, dst = src[blockSize:], dst[blockSize:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HChaCha20 uses the ChaCha20 core to generate a derived key from a 32 bytes
|
||||||
|
// key and a 16 bytes nonce. It returns an error if key or nonce have any other
|
||||||
|
// length. It is used as part of the XChaCha20 construction.
|
||||||
|
func HChaCha20(key, nonce []byte) ([]byte, error) {
|
||||||
|
// This function is split into a wrapper so that the slice allocation will
|
||||||
|
// be inlined, and depending on how the caller uses the return value, won't
|
||||||
|
// escape to the heap.
|
||||||
|
out := make([]byte, 32)
|
||||||
|
return hChaCha20(out, key, nonce)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hChaCha20(out, key, nonce []byte) ([]byte, error) {
|
||||||
|
if len(key) != KeySize {
|
||||||
|
return nil, errors.New("chacha20: wrong HChaCha20 key size")
|
||||||
|
}
|
||||||
|
if len(nonce) != 16 {
|
||||||
|
return nil, errors.New("chacha20: wrong HChaCha20 nonce size")
|
||||||
|
}
|
||||||
|
|
||||||
|
x0, x1, x2, x3 := j0, j1, j2, j3
|
||||||
|
x4 := binary.LittleEndian.Uint32(key[0:4])
|
||||||
|
x5 := binary.LittleEndian.Uint32(key[4:8])
|
||||||
|
x6 := binary.LittleEndian.Uint32(key[8:12])
|
||||||
|
x7 := binary.LittleEndian.Uint32(key[12:16])
|
||||||
|
x8 := binary.LittleEndian.Uint32(key[16:20])
|
||||||
|
x9 := binary.LittleEndian.Uint32(key[20:24])
|
||||||
|
x10 := binary.LittleEndian.Uint32(key[24:28])
|
||||||
|
x11 := binary.LittleEndian.Uint32(key[28:32])
|
||||||
|
x12 := binary.LittleEndian.Uint32(nonce[0:4])
|
||||||
|
x13 := binary.LittleEndian.Uint32(nonce[4:8])
|
||||||
|
x14 := binary.LittleEndian.Uint32(nonce[8:12])
|
||||||
|
x15 := binary.LittleEndian.Uint32(nonce[12:16])
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
// Diagonal round.
|
||||||
|
x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12)
|
||||||
|
x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13)
|
||||||
|
x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14)
|
||||||
|
x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15)
|
||||||
|
|
||||||
|
// Column round.
|
||||||
|
x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15)
|
||||||
|
x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12)
|
||||||
|
x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13)
|
||||||
|
x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = out[31] // bounds check elimination hint
|
||||||
|
binary.LittleEndian.PutUint32(out[0:4], x0)
|
||||||
|
binary.LittleEndian.PutUint32(out[4:8], x1)
|
||||||
|
binary.LittleEndian.PutUint32(out[8:12], x2)
|
||||||
|
binary.LittleEndian.PutUint32(out[12:16], x3)
|
||||||
|
binary.LittleEndian.PutUint32(out[16:20], x12)
|
||||||
|
binary.LittleEndian.PutUint32(out[20:24], x13)
|
||||||
|
binary.LittleEndian.PutUint32(out[24:28], x14)
|
||||||
|
binary.LittleEndian.PutUint32(out[28:32], x15)
|
||||||
|
return out, nil
|
||||||
|
}
|
13
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
generated
vendored
Normal file
13
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build (!arm64 && !s390x && !ppc64le) || !gc || purego
|
||||||
|
|
||||||
|
package chacha20
|
||||||
|
|
||||||
|
const bufSize = blockSize
|
||||||
|
|
||||||
|
func (s *Cipher) xorKeyStreamBlocks(dst, src []byte) {
|
||||||
|
s.xorKeyStreamBlocksGeneric(dst, src)
|
||||||
|
}
|
16
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
generated
vendored
Normal file
16
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gc && !purego
|
||||||
|
|
||||||
|
package chacha20
|
||||||
|
|
||||||
|
const bufSize = 256
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)
|
||||||
|
|
||||||
|
func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {
|
||||||
|
chaCha20_ctr32_vsx(&dst[0], &src[0], len(src), &c.key, &c.counter)
|
||||||
|
}
|
443
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
generated
vendored
Normal file
443
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
generated
vendored
Normal file
|
@ -0,0 +1,443 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Based on CRYPTOGAMS code with the following comment:
|
||||||
|
// # ====================================================================
|
||||||
|
// # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
|
||||||
|
// # project. The module is, however, dual licensed under OpenSSL and
|
||||||
|
// # CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||||
|
// # details see http://www.openssl.org/~appro/cryptogams/.
|
||||||
|
// # ====================================================================
|
||||||
|
|
||||||
|
// Code for the perl script that generates the ppc64 assembler
|
||||||
|
// can be found in the cryptogams repository at the link below. It is based on
|
||||||
|
// the original from openssl.
|
||||||
|
|
||||||
|
// https://github.com/dot-asm/cryptogams/commit/a60f5b50ed908e91
|
||||||
|
|
||||||
|
// The differences in this and the original implementation are
|
||||||
|
// due to the calling conventions and initialization of constants.
|
||||||
|
|
||||||
|
//go:build gc && !purego
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
#define OUT R3
|
||||||
|
#define INP R4
|
||||||
|
#define LEN R5
|
||||||
|
#define KEY R6
|
||||||
|
#define CNT R7
|
||||||
|
#define TMP R15
|
||||||
|
|
||||||
|
#define CONSTBASE R16
|
||||||
|
#define BLOCKS R17
|
||||||
|
|
||||||
|
// for VPERMXOR
|
||||||
|
#define MASK R18
|
||||||
|
|
||||||
|
DATA consts<>+0x00(SB)/8, $0x3320646e61707865
|
||||||
|
DATA consts<>+0x08(SB)/8, $0x6b20657479622d32
|
||||||
|
DATA consts<>+0x10(SB)/8, $0x0000000000000001
|
||||||
|
DATA consts<>+0x18(SB)/8, $0x0000000000000000
|
||||||
|
DATA consts<>+0x20(SB)/8, $0x0000000000000004
|
||||||
|
DATA consts<>+0x28(SB)/8, $0x0000000000000000
|
||||||
|
DATA consts<>+0x30(SB)/8, $0x0a0b08090e0f0c0d
|
||||||
|
DATA consts<>+0x38(SB)/8, $0x0203000106070405
|
||||||
|
DATA consts<>+0x40(SB)/8, $0x090a0b080d0e0f0c
|
||||||
|
DATA consts<>+0x48(SB)/8, $0x0102030005060704
|
||||||
|
DATA consts<>+0x50(SB)/8, $0x6170786561707865
|
||||||
|
DATA consts<>+0x58(SB)/8, $0x6170786561707865
|
||||||
|
DATA consts<>+0x60(SB)/8, $0x3320646e3320646e
|
||||||
|
DATA consts<>+0x68(SB)/8, $0x3320646e3320646e
|
||||||
|
DATA consts<>+0x70(SB)/8, $0x79622d3279622d32
|
||||||
|
DATA consts<>+0x78(SB)/8, $0x79622d3279622d32
|
||||||
|
DATA consts<>+0x80(SB)/8, $0x6b2065746b206574
|
||||||
|
DATA consts<>+0x88(SB)/8, $0x6b2065746b206574
|
||||||
|
DATA consts<>+0x90(SB)/8, $0x0000000100000000
|
||||||
|
DATA consts<>+0x98(SB)/8, $0x0000000300000002
|
||||||
|
DATA consts<>+0xa0(SB)/8, $0x5566774411223300
|
||||||
|
DATA consts<>+0xa8(SB)/8, $0xddeeffcc99aabb88
|
||||||
|
DATA consts<>+0xb0(SB)/8, $0x6677445522330011
|
||||||
|
DATA consts<>+0xb8(SB)/8, $0xeeffccddaabb8899
|
||||||
|
GLOBL consts<>(SB), RODATA, $0xc0
|
||||||
|
|
||||||
|
//func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)
|
||||||
|
TEXT ·chaCha20_ctr32_vsx(SB),NOSPLIT,$64-40
|
||||||
|
MOVD out+0(FP), OUT
|
||||||
|
MOVD inp+8(FP), INP
|
||||||
|
MOVD len+16(FP), LEN
|
||||||
|
MOVD key+24(FP), KEY
|
||||||
|
MOVD counter+32(FP), CNT
|
||||||
|
|
||||||
|
// Addressing for constants
|
||||||
|
MOVD $consts<>+0x00(SB), CONSTBASE
|
||||||
|
MOVD $16, R8
|
||||||
|
MOVD $32, R9
|
||||||
|
MOVD $48, R10
|
||||||
|
MOVD $64, R11
|
||||||
|
SRD $6, LEN, BLOCKS
|
||||||
|
// for VPERMXOR
|
||||||
|
MOVD $consts<>+0xa0(SB), MASK
|
||||||
|
MOVD $16, R20
|
||||||
|
// V16
|
||||||
|
LXVW4X (CONSTBASE)(R0), VS48
|
||||||
|
ADD $80,CONSTBASE
|
||||||
|
|
||||||
|
// Load key into V17,V18
|
||||||
|
LXVW4X (KEY)(R0), VS49
|
||||||
|
LXVW4X (KEY)(R8), VS50
|
||||||
|
|
||||||
|
// Load CNT, NONCE into V19
|
||||||
|
LXVW4X (CNT)(R0), VS51
|
||||||
|
|
||||||
|
// Clear V27
|
||||||
|
VXOR V27, V27, V27
|
||||||
|
|
||||||
|
// V28
|
||||||
|
LXVW4X (CONSTBASE)(R11), VS60
|
||||||
|
|
||||||
|
// Load mask constants for VPERMXOR
|
||||||
|
LXVW4X (MASK)(R0), V20
|
||||||
|
LXVW4X (MASK)(R20), V21
|
||||||
|
|
||||||
|
// splat slot from V19 -> V26
|
||||||
|
VSPLTW $0, V19, V26
|
||||||
|
|
||||||
|
VSLDOI $4, V19, V27, V19
|
||||||
|
VSLDOI $12, V27, V19, V19
|
||||||
|
|
||||||
|
VADDUWM V26, V28, V26
|
||||||
|
|
||||||
|
MOVD $10, R14
|
||||||
|
MOVD R14, CTR
|
||||||
|
PCALIGN $16
|
||||||
|
loop_outer_vsx:
|
||||||
|
// V0, V1, V2, V3
|
||||||
|
LXVW4X (R0)(CONSTBASE), VS32
|
||||||
|
LXVW4X (R8)(CONSTBASE), VS33
|
||||||
|
LXVW4X (R9)(CONSTBASE), VS34
|
||||||
|
LXVW4X (R10)(CONSTBASE), VS35
|
||||||
|
|
||||||
|
// splat values from V17, V18 into V4-V11
|
||||||
|
VSPLTW $0, V17, V4
|
||||||
|
VSPLTW $1, V17, V5
|
||||||
|
VSPLTW $2, V17, V6
|
||||||
|
VSPLTW $3, V17, V7
|
||||||
|
VSPLTW $0, V18, V8
|
||||||
|
VSPLTW $1, V18, V9
|
||||||
|
VSPLTW $2, V18, V10
|
||||||
|
VSPLTW $3, V18, V11
|
||||||
|
|
||||||
|
// VOR
|
||||||
|
VOR V26, V26, V12
|
||||||
|
|
||||||
|
// splat values from V19 -> V13, V14, V15
|
||||||
|
VSPLTW $1, V19, V13
|
||||||
|
VSPLTW $2, V19, V14
|
||||||
|
VSPLTW $3, V19, V15
|
||||||
|
|
||||||
|
// splat const values
|
||||||
|
VSPLTISW $-16, V27
|
||||||
|
VSPLTISW $12, V28
|
||||||
|
VSPLTISW $8, V29
|
||||||
|
VSPLTISW $7, V30
|
||||||
|
PCALIGN $16
|
||||||
|
loop_vsx:
|
||||||
|
VADDUWM V0, V4, V0
|
||||||
|
VADDUWM V1, V5, V1
|
||||||
|
VADDUWM V2, V6, V2
|
||||||
|
VADDUWM V3, V7, V3
|
||||||
|
|
||||||
|
VPERMXOR V12, V0, V21, V12
|
||||||
|
VPERMXOR V13, V1, V21, V13
|
||||||
|
VPERMXOR V14, V2, V21, V14
|
||||||
|
VPERMXOR V15, V3, V21, V15
|
||||||
|
|
||||||
|
VADDUWM V8, V12, V8
|
||||||
|
VADDUWM V9, V13, V9
|
||||||
|
VADDUWM V10, V14, V10
|
||||||
|
VADDUWM V11, V15, V11
|
||||||
|
|
||||||
|
VXOR V4, V8, V4
|
||||||
|
VXOR V5, V9, V5
|
||||||
|
VXOR V6, V10, V6
|
||||||
|
VXOR V7, V11, V7
|
||||||
|
|
||||||
|
VRLW V4, V28, V4
|
||||||
|
VRLW V5, V28, V5
|
||||||
|
VRLW V6, V28, V6
|
||||||
|
VRLW V7, V28, V7
|
||||||
|
|
||||||
|
VADDUWM V0, V4, V0
|
||||||
|
VADDUWM V1, V5, V1
|
||||||
|
VADDUWM V2, V6, V2
|
||||||
|
VADDUWM V3, V7, V3
|
||||||
|
|
||||||
|
VPERMXOR V12, V0, V20, V12
|
||||||
|
VPERMXOR V13, V1, V20, V13
|
||||||
|
VPERMXOR V14, V2, V20, V14
|
||||||
|
VPERMXOR V15, V3, V20, V15
|
||||||
|
|
||||||
|
VADDUWM V8, V12, V8
|
||||||
|
VADDUWM V9, V13, V9
|
||||||
|
VADDUWM V10, V14, V10
|
||||||
|
VADDUWM V11, V15, V11
|
||||||
|
|
||||||
|
VXOR V4, V8, V4
|
||||||
|
VXOR V5, V9, V5
|
||||||
|
VXOR V6, V10, V6
|
||||||
|
VXOR V7, V11, V7
|
||||||
|
|
||||||
|
VRLW V4, V30, V4
|
||||||
|
VRLW V5, V30, V5
|
||||||
|
VRLW V6, V30, V6
|
||||||
|
VRLW V7, V30, V7
|
||||||
|
|
||||||
|
VADDUWM V0, V5, V0
|
||||||
|
VADDUWM V1, V6, V1
|
||||||
|
VADDUWM V2, V7, V2
|
||||||
|
VADDUWM V3, V4, V3
|
||||||
|
|
||||||
|
VPERMXOR V15, V0, V21, V15
|
||||||
|
VPERMXOR V12, V1, V21, V12
|
||||||
|
VPERMXOR V13, V2, V21, V13
|
||||||
|
VPERMXOR V14, V3, V21, V14
|
||||||
|
|
||||||
|
VADDUWM V10, V15, V10
|
||||||
|
VADDUWM V11, V12, V11
|
||||||
|
VADDUWM V8, V13, V8
|
||||||
|
VADDUWM V9, V14, V9
|
||||||
|
|
||||||
|
VXOR V5, V10, V5
|
||||||
|
VXOR V6, V11, V6
|
||||||
|
VXOR V7, V8, V7
|
||||||
|
VXOR V4, V9, V4
|
||||||
|
|
||||||
|
VRLW V5, V28, V5
|
||||||
|
VRLW V6, V28, V6
|
||||||
|
VRLW V7, V28, V7
|
||||||
|
VRLW V4, V28, V4
|
||||||
|
|
||||||
|
VADDUWM V0, V5, V0
|
||||||
|
VADDUWM V1, V6, V1
|
||||||
|
VADDUWM V2, V7, V2
|
||||||
|
VADDUWM V3, V4, V3
|
||||||
|
|
||||||
|
VPERMXOR V15, V0, V20, V15
|
||||||
|
VPERMXOR V12, V1, V20, V12
|
||||||
|
VPERMXOR V13, V2, V20, V13
|
||||||
|
VPERMXOR V14, V3, V20, V14
|
||||||
|
|
||||||
|
VADDUWM V10, V15, V10
|
||||||
|
VADDUWM V11, V12, V11
|
||||||
|
VADDUWM V8, V13, V8
|
||||||
|
VADDUWM V9, V14, V9
|
||||||
|
|
||||||
|
VXOR V5, V10, V5
|
||||||
|
VXOR V6, V11, V6
|
||||||
|
VXOR V7, V8, V7
|
||||||
|
VXOR V4, V9, V4
|
||||||
|
|
||||||
|
VRLW V5, V30, V5
|
||||||
|
VRLW V6, V30, V6
|
||||||
|
VRLW V7, V30, V7
|
||||||
|
VRLW V4, V30, V4
|
||||||
|
BDNZ loop_vsx
|
||||||
|
|
||||||
|
VADDUWM V12, V26, V12
|
||||||
|
|
||||||
|
VMRGEW V0, V1, V27
|
||||||
|
VMRGEW V2, V3, V28
|
||||||
|
|
||||||
|
VMRGOW V0, V1, V0
|
||||||
|
VMRGOW V2, V3, V2
|
||||||
|
|
||||||
|
VMRGEW V4, V5, V29
|
||||||
|
VMRGEW V6, V7, V30
|
||||||
|
|
||||||
|
XXPERMDI VS32, VS34, $0, VS33
|
||||||
|
XXPERMDI VS32, VS34, $3, VS35
|
||||||
|
XXPERMDI VS59, VS60, $0, VS32
|
||||||
|
XXPERMDI VS59, VS60, $3, VS34
|
||||||
|
|
||||||
|
VMRGOW V4, V5, V4
|
||||||
|
VMRGOW V6, V7, V6
|
||||||
|
|
||||||
|
VMRGEW V8, V9, V27
|
||||||
|
VMRGEW V10, V11, V28
|
||||||
|
|
||||||
|
XXPERMDI VS36, VS38, $0, VS37
|
||||||
|
XXPERMDI VS36, VS38, $3, VS39
|
||||||
|
XXPERMDI VS61, VS62, $0, VS36
|
||||||
|
XXPERMDI VS61, VS62, $3, VS38
|
||||||
|
|
||||||
|
VMRGOW V8, V9, V8
|
||||||
|
VMRGOW V10, V11, V10
|
||||||
|
|
||||||
|
VMRGEW V12, V13, V29
|
||||||
|
VMRGEW V14, V15, V30
|
||||||
|
|
||||||
|
XXPERMDI VS40, VS42, $0, VS41
|
||||||
|
XXPERMDI VS40, VS42, $3, VS43
|
||||||
|
XXPERMDI VS59, VS60, $0, VS40
|
||||||
|
XXPERMDI VS59, VS60, $3, VS42
|
||||||
|
|
||||||
|
VMRGOW V12, V13, V12
|
||||||
|
VMRGOW V14, V15, V14
|
||||||
|
|
||||||
|
VSPLTISW $4, V27
|
||||||
|
VADDUWM V26, V27, V26
|
||||||
|
|
||||||
|
XXPERMDI VS44, VS46, $0, VS45
|
||||||
|
XXPERMDI VS44, VS46, $3, VS47
|
||||||
|
XXPERMDI VS61, VS62, $0, VS44
|
||||||
|
XXPERMDI VS61, VS62, $3, VS46
|
||||||
|
|
||||||
|
VADDUWM V0, V16, V0
|
||||||
|
VADDUWM V4, V17, V4
|
||||||
|
VADDUWM V8, V18, V8
|
||||||
|
VADDUWM V12, V19, V12
|
||||||
|
|
||||||
|
CMPU LEN, $64
|
||||||
|
BLT tail_vsx
|
||||||
|
|
||||||
|
// Bottom of loop
|
||||||
|
LXVW4X (INP)(R0), VS59
|
||||||
|
LXVW4X (INP)(R8), VS60
|
||||||
|
LXVW4X (INP)(R9), VS61
|
||||||
|
LXVW4X (INP)(R10), VS62
|
||||||
|
|
||||||
|
VXOR V27, V0, V27
|
||||||
|
VXOR V28, V4, V28
|
||||||
|
VXOR V29, V8, V29
|
||||||
|
VXOR V30, V12, V30
|
||||||
|
|
||||||
|
STXVW4X VS59, (OUT)(R0)
|
||||||
|
STXVW4X VS60, (OUT)(R8)
|
||||||
|
ADD $64, INP
|
||||||
|
STXVW4X VS61, (OUT)(R9)
|
||||||
|
ADD $-64, LEN
|
||||||
|
STXVW4X VS62, (OUT)(R10)
|
||||||
|
ADD $64, OUT
|
||||||
|
BEQ done_vsx
|
||||||
|
|
||||||
|
VADDUWM V1, V16, V0
|
||||||
|
VADDUWM V5, V17, V4
|
||||||
|
VADDUWM V9, V18, V8
|
||||||
|
VADDUWM V13, V19, V12
|
||||||
|
|
||||||
|
CMPU LEN, $64
|
||||||
|
BLT tail_vsx
|
||||||
|
|
||||||
|
LXVW4X (INP)(R0), VS59
|
||||||
|
LXVW4X (INP)(R8), VS60
|
||||||
|
LXVW4X (INP)(R9), VS61
|
||||||
|
LXVW4X (INP)(R10), VS62
|
||||||
|
VXOR V27, V0, V27
|
||||||
|
|
||||||
|
VXOR V28, V4, V28
|
||||||
|
VXOR V29, V8, V29
|
||||||
|
VXOR V30, V12, V30
|
||||||
|
|
||||||
|
STXVW4X VS59, (OUT)(R0)
|
||||||
|
STXVW4X VS60, (OUT)(R8)
|
||||||
|
ADD $64, INP
|
||||||
|
STXVW4X VS61, (OUT)(R9)
|
||||||
|
ADD $-64, LEN
|
||||||
|
STXVW4X VS62, (OUT)(V10)
|
||||||
|
ADD $64, OUT
|
||||||
|
BEQ done_vsx
|
||||||
|
|
||||||
|
VADDUWM V2, V16, V0
|
||||||
|
VADDUWM V6, V17, V4
|
||||||
|
VADDUWM V10, V18, V8
|
||||||
|
VADDUWM V14, V19, V12
|
||||||
|
|
||||||
|
CMPU LEN, $64
|
||||||
|
BLT tail_vsx
|
||||||
|
|
||||||
|
LXVW4X (INP)(R0), VS59
|
||||||
|
LXVW4X (INP)(R8), VS60
|
||||||
|
LXVW4X (INP)(R9), VS61
|
||||||
|
LXVW4X (INP)(R10), VS62
|
||||||
|
|
||||||
|
VXOR V27, V0, V27
|
||||||
|
VXOR V28, V4, V28
|
||||||
|
VXOR V29, V8, V29
|
||||||
|
VXOR V30, V12, V30
|
||||||
|
|
||||||
|
STXVW4X VS59, (OUT)(R0)
|
||||||
|
STXVW4X VS60, (OUT)(R8)
|
||||||
|
ADD $64, INP
|
||||||
|
STXVW4X VS61, (OUT)(R9)
|
||||||
|
ADD $-64, LEN
|
||||||
|
STXVW4X VS62, (OUT)(R10)
|
||||||
|
ADD $64, OUT
|
||||||
|
BEQ done_vsx
|
||||||
|
|
||||||
|
VADDUWM V3, V16, V0
|
||||||
|
VADDUWM V7, V17, V4
|
||||||
|
VADDUWM V11, V18, V8
|
||||||
|
VADDUWM V15, V19, V12
|
||||||
|
|
||||||
|
CMPU LEN, $64
|
||||||
|
BLT tail_vsx
|
||||||
|
|
||||||
|
LXVW4X (INP)(R0), VS59
|
||||||
|
LXVW4X (INP)(R8), VS60
|
||||||
|
LXVW4X (INP)(R9), VS61
|
||||||
|
LXVW4X (INP)(R10), VS62
|
||||||
|
|
||||||
|
VXOR V27, V0, V27
|
||||||
|
VXOR V28, V4, V28
|
||||||
|
VXOR V29, V8, V29
|
||||||
|
VXOR V30, V12, V30
|
||||||
|
|
||||||
|
STXVW4X VS59, (OUT)(R0)
|
||||||
|
STXVW4X VS60, (OUT)(R8)
|
||||||
|
ADD $64, INP
|
||||||
|
STXVW4X VS61, (OUT)(R9)
|
||||||
|
ADD $-64, LEN
|
||||||
|
STXVW4X VS62, (OUT)(R10)
|
||||||
|
ADD $64, OUT
|
||||||
|
|
||||||
|
MOVD $10, R14
|
||||||
|
MOVD R14, CTR
|
||||||
|
BNE loop_outer_vsx
|
||||||
|
|
||||||
|
done_vsx:
|
||||||
|
// Increment counter by number of 64 byte blocks
|
||||||
|
MOVD (CNT), R14
|
||||||
|
ADD BLOCKS, R14
|
||||||
|
MOVD R14, (CNT)
|
||||||
|
RET
|
||||||
|
|
||||||
|
tail_vsx:
|
||||||
|
ADD $32, R1, R11
|
||||||
|
MOVD LEN, CTR
|
||||||
|
|
||||||
|
// Save values on stack to copy from
|
||||||
|
STXVW4X VS32, (R11)(R0)
|
||||||
|
STXVW4X VS36, (R11)(R8)
|
||||||
|
STXVW4X VS40, (R11)(R9)
|
||||||
|
STXVW4X VS44, (R11)(R10)
|
||||||
|
ADD $-1, R11, R12
|
||||||
|
ADD $-1, INP
|
||||||
|
ADD $-1, OUT
|
||||||
|
PCALIGN $16
|
||||||
|
looptail_vsx:
|
||||||
|
// Copying the result to OUT
|
||||||
|
// in bytes.
|
||||||
|
MOVBZU 1(R12), KEY
|
||||||
|
MOVBZU 1(INP), TMP
|
||||||
|
XOR KEY, TMP, KEY
|
||||||
|
MOVBU KEY, 1(OUT)
|
||||||
|
BDNZ looptail_vsx
|
||||||
|
|
||||||
|
// Clear the stack values
|
||||||
|
STXVW4X VS48, (R11)(R0)
|
||||||
|
STXVW4X VS48, (R11)(R8)
|
||||||
|
STXVW4X VS48, (R11)(R9)
|
||||||
|
STXVW4X VS48, (R11)(R10)
|
||||||
|
BR done_vsx
|
27
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
generated
vendored
Normal file
27
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gc && !purego
|
||||||
|
|
||||||
|
package chacha20
|
||||||
|
|
||||||
|
import "golang.org/x/sys/cpu"
|
||||||
|
|
||||||
|
var haveAsm = cpu.S390X.HasVX
|
||||||
|
|
||||||
|
const bufSize = 256
|
||||||
|
|
||||||
|
// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
|
||||||
|
// be called when the vector facility is available. Implementation in asm_s390x.s.
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
|
||||||
|
|
||||||
|
func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {
|
||||||
|
if cpu.S390X.HasVX {
|
||||||
|
xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter)
|
||||||
|
} else {
|
||||||
|
c.xorKeyStreamBlocksGeneric(dst, src)
|
||||||
|
}
|
||||||
|
}
|
224
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
generated
vendored
Normal file
224
cli/v2/picocrypt/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
generated
vendored
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gc && !purego
|
||||||
|
|
||||||
|
#include "go_asm.h"
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// This is an implementation of the ChaCha20 encryption algorithm as
|
||||||
|
// specified in RFC 7539. It uses vector instructions to compute
|
||||||
|
// 4 keystream blocks in parallel (256 bytes) which are then XORed
|
||||||
|
// with the bytes in the input slice.
|
||||||
|
|
||||||
|
GLOBL ·constants<>(SB), RODATA|NOPTR, $32
|
||||||
|
// BSWAP: swap bytes in each 4-byte element
|
||||||
|
DATA ·constants<>+0x00(SB)/4, $0x03020100
|
||||||
|
DATA ·constants<>+0x04(SB)/4, $0x07060504
|
||||||
|
DATA ·constants<>+0x08(SB)/4, $0x0b0a0908
|
||||||
|
DATA ·constants<>+0x0c(SB)/4, $0x0f0e0d0c
|
||||||
|
// J0: [j0, j1, j2, j3]
|
||||||
|
DATA ·constants<>+0x10(SB)/4, $0x61707865
|
||||||
|
DATA ·constants<>+0x14(SB)/4, $0x3320646e
|
||||||
|
DATA ·constants<>+0x18(SB)/4, $0x79622d32
|
||||||
|
DATA ·constants<>+0x1c(SB)/4, $0x6b206574
|
||||||
|
|
||||||
|
#define BSWAP V5
|
||||||
|
#define J0 V6
|
||||||
|
#define KEY0 V7
|
||||||
|
#define KEY1 V8
|
||||||
|
#define NONCE V9
|
||||||
|
#define CTR V10
|
||||||
|
#define M0 V11
|
||||||
|
#define M1 V12
|
||||||
|
#define M2 V13
|
||||||
|
#define M3 V14
|
||||||
|
#define INC V15
|
||||||
|
#define X0 V16
|
||||||
|
#define X1 V17
|
||||||
|
#define X2 V18
|
||||||
|
#define X3 V19
|
||||||
|
#define X4 V20
|
||||||
|
#define X5 V21
|
||||||
|
#define X6 V22
|
||||||
|
#define X7 V23
|
||||||
|
#define X8 V24
|
||||||
|
#define X9 V25
|
||||||
|
#define X10 V26
|
||||||
|
#define X11 V27
|
||||||
|
#define X12 V28
|
||||||
|
#define X13 V29
|
||||||
|
#define X14 V30
|
||||||
|
#define X15 V31
|
||||||
|
|
||||||
|
#define NUM_ROUNDS 20
|
||||||
|
|
||||||
|
#define ROUND4(a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3, d0, d1, d2, d3) \
|
||||||
|
VAF a1, a0, a0 \
|
||||||
|
VAF b1, b0, b0 \
|
||||||
|
VAF c1, c0, c0 \
|
||||||
|
VAF d1, d0, d0 \
|
||||||
|
VX a0, a2, a2 \
|
||||||
|
VX b0, b2, b2 \
|
||||||
|
VX c0, c2, c2 \
|
||||||
|
VX d0, d2, d2 \
|
||||||
|
VERLLF $16, a2, a2 \
|
||||||
|
VERLLF $16, b2, b2 \
|
||||||
|
VERLLF $16, c2, c2 \
|
||||||
|
VERLLF $16, d2, d2 \
|
||||||
|
VAF a2, a3, a3 \
|
||||||
|
VAF b2, b3, b3 \
|
||||||
|
VAF c2, c3, c3 \
|
||||||
|
VAF d2, d3, d3 \
|
||||||
|
VX a3, a1, a1 \
|
||||||
|
VX b3, b1, b1 \
|
||||||
|
VX c3, c1, c1 \
|
||||||
|
VX d3, d1, d1 \
|
||||||
|
VERLLF $12, a1, a1 \
|
||||||
|
VERLLF $12, b1, b1 \
|
||||||
|
VERLLF $12, c1, c1 \
|
||||||
|
VERLLF $12, d1, d1 \
|
||||||
|
VAF a1, a0, a0 \
|
||||||
|
VAF b1, b0, b0 \
|
||||||
|
VAF c1, c0, c0 \
|
||||||
|
VAF d1, d0, d0 \
|
||||||
|
VX a0, a2, a2 \
|
||||||
|
VX b0, b2, b2 \
|
||||||
|
VX c0, c2, c2 \
|
||||||
|
VX d0, d2, d2 \
|
||||||
|
VERLLF $8, a2, a2 \
|
||||||
|
VERLLF $8, b2, b2 \
|
||||||
|
VERLLF $8, c2, c2 \
|
||||||
|
VERLLF $8, d2, d2 \
|
||||||
|
VAF a2, a3, a3 \
|
||||||
|
VAF b2, b3, b3 \
|
||||||
|
VAF c2, c3, c3 \
|
||||||
|
VAF d2, d3, d3 \
|
||||||
|
VX a3, a1, a1 \
|
||||||
|
VX b3, b1, b1 \
|
||||||
|
VX c3, c1, c1 \
|
||||||
|
VX d3, d1, d1 \
|
||||||
|
VERLLF $7, a1, a1 \
|
||||||
|
VERLLF $7, b1, b1 \
|
||||||
|
VERLLF $7, c1, c1 \
|
||||||
|
VERLLF $7, d1, d1
|
||||||
|
|
||||||
|
#define PERMUTE(mask, v0, v1, v2, v3) \
|
||||||
|
VPERM v0, v0, mask, v0 \
|
||||||
|
VPERM v1, v1, mask, v1 \
|
||||||
|
VPERM v2, v2, mask, v2 \
|
||||||
|
VPERM v3, v3, mask, v3
|
||||||
|
|
||||||
|
#define ADDV(x, v0, v1, v2, v3) \
|
||||||
|
VAF x, v0, v0 \
|
||||||
|
VAF x, v1, v1 \
|
||||||
|
VAF x, v2, v2 \
|
||||||
|
VAF x, v3, v3
|
||||||
|
|
||||||
|
#define XORV(off, dst, src, v0, v1, v2, v3) \
|
||||||
|
VLM off(src), M0, M3 \
|
||||||
|
PERMUTE(BSWAP, v0, v1, v2, v3) \
|
||||||
|
VX v0, M0, M0 \
|
||||||
|
VX v1, M1, M1 \
|
||||||
|
VX v2, M2, M2 \
|
||||||
|
VX v3, M3, M3 \
|
||||||
|
VSTM M0, M3, off(dst)
|
||||||
|
|
||||||
|
#define SHUFFLE(a, b, c, d, t, u, v, w) \
|
||||||
|
VMRHF a, c, t \ // t = {a[0], c[0], a[1], c[1]}
|
||||||
|
VMRHF b, d, u \ // u = {b[0], d[0], b[1], d[1]}
|
||||||
|
VMRLF a, c, v \ // v = {a[2], c[2], a[3], c[3]}
|
||||||
|
VMRLF b, d, w \ // w = {b[2], d[2], b[3], d[3]}
|
||||||
|
VMRHF t, u, a \ // a = {a[0], b[0], c[0], d[0]}
|
||||||
|
VMRLF t, u, b \ // b = {a[1], b[1], c[1], d[1]}
|
||||||
|
VMRHF v, w, c \ // c = {a[2], b[2], c[2], d[2]}
|
||||||
|
VMRLF v, w, d // d = {a[3], b[3], c[3], d[3]}
|
||||||
|
|
||||||
|
// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
|
||||||
|
TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0
|
||||||
|
MOVD $·constants<>(SB), R1
|
||||||
|
MOVD dst+0(FP), R2 // R2=&dst[0]
|
||||||
|
LMG src+24(FP), R3, R4 // R3=&src[0] R4=len(src)
|
||||||
|
MOVD key+48(FP), R5 // R5=key
|
||||||
|
MOVD nonce+56(FP), R6 // R6=nonce
|
||||||
|
MOVD counter+64(FP), R7 // R7=counter
|
||||||
|
|
||||||
|
// load BSWAP and J0
|
||||||
|
VLM (R1), BSWAP, J0
|
||||||
|
|
||||||
|
// setup
|
||||||
|
MOVD $95, R0
|
||||||
|
VLM (R5), KEY0, KEY1
|
||||||
|
VLL R0, (R6), NONCE
|
||||||
|
VZERO M0
|
||||||
|
VLEIB $7, $32, M0
|
||||||
|
VSRLB M0, NONCE, NONCE
|
||||||
|
|
||||||
|
// initialize counter values
|
||||||
|
VLREPF (R7), CTR
|
||||||
|
VZERO INC
|
||||||
|
VLEIF $1, $1, INC
|
||||||
|
VLEIF $2, $2, INC
|
||||||
|
VLEIF $3, $3, INC
|
||||||
|
VAF INC, CTR, CTR
|
||||||
|
VREPIF $4, INC
|
||||||
|
|
||||||
|
chacha:
|
||||||
|
VREPF $0, J0, X0
|
||||||
|
VREPF $1, J0, X1
|
||||||
|
VREPF $2, J0, X2
|
||||||
|
VREPF $3, J0, X3
|
||||||
|
VREPF $0, KEY0, X4
|
||||||
|
VREPF $1, KEY0, X5
|
||||||
|
VREPF $2, KEY0, X6
|
||||||
|
VREPF $3, KEY0, X7
|
||||||
|
VREPF $0, KEY1, X8
|
||||||
|
VREPF $1, KEY1, X9
|
||||||
|
VREPF $2, KEY1, X10
|
||||||
|
VREPF $3, KEY1, X11
|
||||||
|
VLR CTR, X12
|
||||||
|
VREPF $1, NONCE, X13
|
||||||
|
VREPF $2, NONCE, X14
|
||||||
|
VREPF $3, NONCE, X15
|
||||||
|
|
||||||
|
MOVD $(NUM_ROUNDS/2), R1
|
||||||
|
|
||||||
|
loop:
|
||||||
|
ROUND4(X0, X4, X12, X8, X1, X5, X13, X9, X2, X6, X14, X10, X3, X7, X15, X11)
|
||||||
|
ROUND4(X0, X5, X15, X10, X1, X6, X12, X11, X2, X7, X13, X8, X3, X4, X14, X9)
|
||||||
|
|
||||||
|
ADD $-1, R1
|
||||||
|
BNE loop
|
||||||
|
|
||||||
|
// decrement length
|
||||||
|
ADD $-256, R4
|
||||||
|
|
||||||
|
// rearrange vectors
|
||||||
|
SHUFFLE(X0, X1, X2, X3, M0, M1, M2, M3)
|
||||||
|
ADDV(J0, X0, X1, X2, X3)
|
||||||
|
SHUFFLE(X4, X5, X6, X7, M0, M1, M2, M3)
|
||||||
|
ADDV(KEY0, X4, X5, X6, X7)
|
||||||
|
SHUFFLE(X8, X9, X10, X11, M0, M1, M2, M3)
|
||||||
|
ADDV(KEY1, X8, X9, X10, X11)
|
||||||
|
VAF CTR, X12, X12
|
||||||
|
SHUFFLE(X12, X13, X14, X15, M0, M1, M2, M3)
|
||||||
|
ADDV(NONCE, X12, X13, X14, X15)
|
||||||
|
|
||||||
|
// increment counters
|
||||||
|
VAF INC, CTR, CTR
|
||||||
|
|
||||||
|
// xor keystream with plaintext
|
||||||
|
XORV(0*64, R2, R3, X0, X4, X8, X12)
|
||||||
|
XORV(1*64, R2, R3, X1, X5, X9, X13)
|
||||||
|
XORV(2*64, R2, R3, X2, X6, X10, X14)
|
||||||
|
XORV(3*64, R2, R3, X3, X7, X11, X15)
|
||||||
|
|
||||||
|
// increment pointers
|
||||||
|
MOVD $256(R2), R2
|
||||||
|
MOVD $256(R3), R3
|
||||||
|
|
||||||
|
CMPBNE R4, $0, chacha
|
||||||
|
|
||||||
|
VSTEF $0, CTR, (R7)
|
||||||
|
RET
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found src the LICENSE file.
|
||||||
|
|
||||||
|
package chacha20
|
||||||
|
|
||||||
|
import "runtime"
|
||||||
|
|
||||||
|
// Platforms that have fast unaligned 32-bit little endian accesses.
|
||||||
|
const unaligned = runtime.GOARCH == "386" ||
|
||||||
|
runtime.GOARCH == "amd64" ||
|
||||||
|
runtime.GOARCH == "arm64" ||
|
||||||
|
runtime.GOARCH == "ppc64le" ||
|
||||||
|
runtime.GOARCH == "s390x"
|
||||||
|
|
||||||
|
// addXor reads a little endian uint32 from src, XORs it with (a + b) and
|
||||||
|
// places the result in little endian byte order in dst.
|
||||||
|
func addXor(dst, src []byte, a, b uint32) {
|
||||||
|
_, _ = src[3], dst[3] // bounds check elimination hint
|
||||||
|
if unaligned {
|
||||||
|
// The compiler should optimize this code into
|
||||||
|
// 32-bit unaligned little endian loads and stores.
|
||||||
|
// TODO: delete once the compiler does a reliably
|
||||||
|
// good job with the generic code below.
|
||||||
|
// See issue #25111 for more details.
|
||||||
|
v := uint32(src[0])
|
||||||
|
v |= uint32(src[1]) << 8
|
||||||
|
v |= uint32(src[2]) << 16
|
||||||
|
v |= uint32(src[3]) << 24
|
||||||
|
v ^= a + b
|
||||||
|
dst[0] = byte(v)
|
||||||
|
dst[1] = byte(v >> 8)
|
||||||
|
dst[2] = byte(v >> 16)
|
||||||
|
dst[3] = byte(v >> 24)
|
||||||
|
} else {
|
||||||
|
a += b
|
||||||
|
dst[0] = src[0] ^ byte(a)
|
||||||
|
dst[1] = src[1] ^ byte(a>>8)
|
||||||
|
dst[2] = src[2] ^ byte(a>>16)
|
||||||
|
dst[3] = src[3] ^ byte(a>>24)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package hkdf implements the HMAC-based Extract-and-Expand Key Derivation
|
||||||
|
// Function (HKDF) as defined in RFC 5869.
|
||||||
|
//
|
||||||
|
// HKDF is a cryptographic key derivation function (KDF) with the goal of
|
||||||
|
// expanding limited input keying material into one or more cryptographically
|
||||||
|
// strong secret keys.
|
||||||
|
package hkdf // import "golang.org/x/crypto/hkdf"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"errors"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Extract generates a pseudorandom key for use with Expand from an input secret
|
||||||
|
// and an optional independent salt.
|
||||||
|
//
|
||||||
|
// Only use this function if you need to reuse the extracted key with multiple
|
||||||
|
// Expand invocations and different context values. Most common scenarios,
|
||||||
|
// including the generation of multiple keys, should use New instead.
|
||||||
|
func Extract(hash func() hash.Hash, secret, salt []byte) []byte {
|
||||||
|
if salt == nil {
|
||||||
|
salt = make([]byte, hash().Size())
|
||||||
|
}
|
||||||
|
extractor := hmac.New(hash, salt)
|
||||||
|
extractor.Write(secret)
|
||||||
|
return extractor.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
type hkdf struct {
|
||||||
|
expander hash.Hash
|
||||||
|
size int
|
||||||
|
|
||||||
|
info []byte
|
||||||
|
counter byte
|
||||||
|
|
||||||
|
prev []byte
|
||||||
|
buf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *hkdf) Read(p []byte) (int, error) {
|
||||||
|
// Check whether enough data can be generated
|
||||||
|
need := len(p)
|
||||||
|
remains := len(f.buf) + int(255-f.counter+1)*f.size
|
||||||
|
if remains < need {
|
||||||
|
return 0, errors.New("hkdf: entropy limit reached")
|
||||||
|
}
|
||||||
|
// Read any leftover from the buffer
|
||||||
|
n := copy(p, f.buf)
|
||||||
|
p = p[n:]
|
||||||
|
|
||||||
|
// Fill the rest of the buffer
|
||||||
|
for len(p) > 0 {
|
||||||
|
if f.counter > 1 {
|
||||||
|
f.expander.Reset()
|
||||||
|
}
|
||||||
|
f.expander.Write(f.prev)
|
||||||
|
f.expander.Write(f.info)
|
||||||
|
f.expander.Write([]byte{f.counter})
|
||||||
|
f.prev = f.expander.Sum(f.prev[:0])
|
||||||
|
f.counter++
|
||||||
|
|
||||||
|
// Copy the new batch into p
|
||||||
|
f.buf = f.prev
|
||||||
|
n = copy(p, f.buf)
|
||||||
|
p = p[n:]
|
||||||
|
}
|
||||||
|
// Save leftovers for next run
|
||||||
|
f.buf = f.buf[n:]
|
||||||
|
|
||||||
|
return need, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand returns a Reader, from which keys can be read, using the given
|
||||||
|
// pseudorandom key and optional context info, skipping the extraction step.
|
||||||
|
//
|
||||||
|
// The pseudorandomKey should have been generated by Extract, or be a uniformly
|
||||||
|
// random or pseudorandom cryptographically strong key. See RFC 5869, Section
|
||||||
|
// 3.3. Most common scenarios will want to use New instead.
|
||||||
|
func Expand(hash func() hash.Hash, pseudorandomKey, info []byte) io.Reader {
|
||||||
|
expander := hmac.New(hash, pseudorandomKey)
|
||||||
|
return &hkdf{expander, expander.Size(), info, 1, nil, nil}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a Reader, from which keys can be read, using the given hash,
|
||||||
|
// secret, salt and context info. Salt and info can be nil.
|
||||||
|
func New(hash func() hash.Hash, secret, salt, info []byte) io.Reader {
|
||||||
|
prk := Extract(hash, secret, salt)
|
||||||
|
return Expand(hash, prk, info)
|
||||||
|
}
|
31
cli/v2/picocrypt/vendor/golang.org/x/crypto/internal/alias/alias.go
generated
vendored
Normal file
31
cli/v2/picocrypt/vendor/golang.org/x/crypto/internal/alias/alias.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !purego
|
||||||
|
|
||||||
|
// Package alias implements memory aliasing tests.
|
||||||
|
package alias
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// AnyOverlap reports whether x and y share memory at any (not necessarily
|
||||||
|
// corresponding) index. The memory beyond the slice length is ignored.
|
||||||
|
func AnyOverlap(x, y []byte) bool {
|
||||||
|
return len(x) > 0 && len(y) > 0 &&
|
||||||
|
uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
|
||||||
|
uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// InexactOverlap reports whether x and y share memory at any non-corresponding
|
||||||
|
// index. The memory beyond the slice length is ignored. Note that x and y can
|
||||||
|
// have different lengths and still not have any inexact overlap.
|
||||||
|
//
|
||||||
|
// InexactOverlap can be used to implement the requirements of the crypto/cipher
|
||||||
|
// AEAD, Block, BlockMode and Stream interfaces.
|
||||||
|
func InexactOverlap(x, y []byte) bool {
|
||||||
|
if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return AnyOverlap(x, y)
|
||||||
|
}
|
34
cli/v2/picocrypt/vendor/golang.org/x/crypto/internal/alias/alias_purego.go
generated
vendored
Normal file
34
cli/v2/picocrypt/vendor/golang.org/x/crypto/internal/alias/alias_purego.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build purego
|
||||||
|
|
||||||
|
// Package alias implements memory aliasing tests.
|
||||||
|
package alias
|
||||||
|
|
||||||
|
// This is the Google App Engine standard variant based on reflect
|
||||||
|
// because the unsafe package and cgo are disallowed.
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
// AnyOverlap reports whether x and y share memory at any (not necessarily
|
||||||
|
// corresponding) index. The memory beyond the slice length is ignored.
|
||||||
|
func AnyOverlap(x, y []byte) bool {
|
||||||
|
return len(x) > 0 && len(y) > 0 &&
|
||||||
|
reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
|
||||||
|
reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// InexactOverlap reports whether x and y share memory at any non-corresponding
|
||||||
|
// index. The memory beyond the slice length is ignored. Note that x and y can
|
||||||
|
// have different lengths and still not have any inexact overlap.
|
||||||
|
//
|
||||||
|
// InexactOverlap can be used to implement the requirements of the crypto/cipher
|
||||||
|
// AEAD, Block, BlockMode and Stream interfaces.
|
||||||
|
func InexactOverlap(x, y []byte) bool {
|
||||||
|
if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return AnyOverlap(x, y)
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package sha3 implements the SHA-3 fixed-output-length hash functions and
|
||||||
|
// the SHAKE variable-output-length hash functions defined by FIPS-202.
|
||||||
|
//
|
||||||
|
// Both types of hash function use the "sponge" construction and the Keccak
|
||||||
|
// permutation. For a detailed specification see http://keccak.noekeon.org/
|
||||||
|
//
|
||||||
|
// # Guidance
|
||||||
|
//
|
||||||
|
// If you aren't sure what function you need, use SHAKE256 with at least 64
|
||||||
|
// bytes of output. The SHAKE instances are faster than the SHA3 instances;
|
||||||
|
// the latter have to allocate memory to conform to the hash.Hash interface.
|
||||||
|
//
|
||||||
|
// If you need a secret-key MAC (message authentication code), prepend the
|
||||||
|
// secret key to the input, hash with SHAKE256 and read at least 32 bytes of
|
||||||
|
// output.
|
||||||
|
//
|
||||||
|
// # Security strengths
|
||||||
|
//
|
||||||
|
// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security
|
||||||
|
// strength against preimage attacks of x bits. Since they only produce "x"
|
||||||
|
// bits of output, their collision-resistance is only "x/2" bits.
|
||||||
|
//
|
||||||
|
// The SHAKE-256 and -128 functions have a generic security strength of 256 and
|
||||||
|
// 128 bits against all attacks, provided that at least 2x bits of their output
|
||||||
|
// is used. Requesting more than 64 or 32 bytes of output, respectively, does
|
||||||
|
// not increase the collision-resistance of the SHAKE functions.
|
||||||
|
//
|
||||||
|
// # The sponge construction
|
||||||
|
//
|
||||||
|
// A sponge builds a pseudo-random function from a public pseudo-random
|
||||||
|
// permutation, by applying the permutation to a state of "rate + capacity"
|
||||||
|
// bytes, but hiding "capacity" of the bytes.
|
||||||
|
//
|
||||||
|
// A sponge starts out with a zero state. To hash an input using a sponge, up
|
||||||
|
// to "rate" bytes of the input are XORed into the sponge's state. The sponge
|
||||||
|
// is then "full" and the permutation is applied to "empty" it. This process is
|
||||||
|
// repeated until all the input has been "absorbed". The input is then padded.
|
||||||
|
// The digest is "squeezed" from the sponge in the same way, except that output
|
||||||
|
// is copied out instead of input being XORed in.
|
||||||
|
//
|
||||||
|
// A sponge is parameterized by its generic security strength, which is equal
|
||||||
|
// to half its capacity; capacity + rate is equal to the permutation's width.
|
||||||
|
// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means
|
||||||
|
// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2.
|
||||||
|
//
|
||||||
|
// # Recommendations
|
||||||
|
//
|
||||||
|
// The SHAKE functions are recommended for most new uses. They can produce
|
||||||
|
// output of arbitrary length. SHAKE256, with an output length of at least
|
||||||
|
// 64 bytes, provides 256-bit security against all attacks. The Keccak team
|
||||||
|
// recommends it for most applications upgrading from SHA2-512. (NIST chose a
|
||||||
|
// much stronger, but much slower, sponge instance for SHA3-512.)
|
||||||
|
//
|
||||||
|
// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions.
|
||||||
|
// They produce output of the same length, with the same security strengths
|
||||||
|
// against all attacks. This means, in particular, that SHA3-256 only has
|
||||||
|
// 128-bit collision resistance, because its output length is 32 bytes.
|
||||||
|
package sha3 // import "golang.org/x/crypto/sha3"
|
|
@ -0,0 +1,97 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// This file provides functions for creating instances of the SHA-3
|
||||||
|
// and SHAKE hash functions, as well as utility functions for hashing
|
||||||
|
// bytes.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New224 creates a new SHA3-224 hash.
|
||||||
|
// Its generic security strength is 224 bits against preimage attacks,
|
||||||
|
// and 112 bits against collision attacks.
|
||||||
|
func New224() hash.Hash {
|
||||||
|
if h := new224Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New256 creates a new SHA3-256 hash.
|
||||||
|
// Its generic security strength is 256 bits against preimage attacks,
|
||||||
|
// and 128 bits against collision attacks.
|
||||||
|
func New256() hash.Hash {
|
||||||
|
if h := new256Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New384 creates a new SHA3-384 hash.
|
||||||
|
// Its generic security strength is 384 bits against preimage attacks,
|
||||||
|
// and 192 bits against collision attacks.
|
||||||
|
func New384() hash.Hash {
|
||||||
|
if h := new384Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New512 creates a new SHA3-512 hash.
|
||||||
|
// Its generic security strength is 512 bits against preimage attacks,
|
||||||
|
// and 256 bits against collision attacks.
|
||||||
|
func New512() hash.Hash {
|
||||||
|
if h := new512Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: 72, outputLen: 64, dsbyte: 0x06}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLegacyKeccak256 creates a new Keccak-256 hash.
|
||||||
|
//
|
||||||
|
// Only use this function if you require compatibility with an existing cryptosystem
|
||||||
|
// that uses non-standard padding. All other users should use New256 instead.
|
||||||
|
func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} }
|
||||||
|
|
||||||
|
// NewLegacyKeccak512 creates a new Keccak-512 hash.
|
||||||
|
//
|
||||||
|
// Only use this function if you require compatibility with an existing cryptosystem
|
||||||
|
// that uses non-standard padding. All other users should use New512 instead.
|
||||||
|
func NewLegacyKeccak512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x01} }
|
||||||
|
|
||||||
|
// Sum224 returns the SHA3-224 digest of the data.
|
||||||
|
func Sum224(data []byte) (digest [28]byte) {
|
||||||
|
h := New224()
|
||||||
|
h.Write(data)
|
||||||
|
h.Sum(digest[:0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum256 returns the SHA3-256 digest of the data.
|
||||||
|
func Sum256(data []byte) (digest [32]byte) {
|
||||||
|
h := New256()
|
||||||
|
h.Write(data)
|
||||||
|
h.Sum(digest[:0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum384 returns the SHA3-384 digest of the data.
|
||||||
|
func Sum384(data []byte) (digest [48]byte) {
|
||||||
|
h := New384()
|
||||||
|
h.Write(data)
|
||||||
|
h.Sum(digest[:0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum512 returns the SHA3-512 digest of the data.
|
||||||
|
func Sum512(data []byte) (digest [64]byte) {
|
||||||
|
h := New512()
|
||||||
|
h.Write(data)
|
||||||
|
h.Sum(digest[:0])
|
||||||
|
return
|
||||||
|
}
|
27
cli/v2/picocrypt/vendor/golang.org/x/crypto/sha3/hashes_generic.go
generated
vendored
Normal file
27
cli/v2/picocrypt/vendor/golang.org/x/crypto/sha3/hashes_generic.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gc || purego || !s390x
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
// new224Asm returns an assembly implementation of SHA3-224 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new224Asm() hash.Hash { return nil }
|
||||||
|
|
||||||
|
// new256Asm returns an assembly implementation of SHA3-256 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new256Asm() hash.Hash { return nil }
|
||||||
|
|
||||||
|
// new384Asm returns an assembly implementation of SHA3-384 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new384Asm() hash.Hash { return nil }
|
||||||
|
|
||||||
|
// new512Asm returns an assembly implementation of SHA3-512 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new512Asm() hash.Hash { return nil }
|
|
@ -0,0 +1,414 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !amd64 || purego || !gc
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
import "math/bits"
|
||||||
|
|
||||||
|
// rc stores the round constants for use in the ι step.
|
||||||
|
var rc = [24]uint64{
|
||||||
|
0x0000000000000001,
|
||||||
|
0x0000000000008082,
|
||||||
|
0x800000000000808A,
|
||||||
|
0x8000000080008000,
|
||||||
|
0x000000000000808B,
|
||||||
|
0x0000000080000001,
|
||||||
|
0x8000000080008081,
|
||||||
|
0x8000000000008009,
|
||||||
|
0x000000000000008A,
|
||||||
|
0x0000000000000088,
|
||||||
|
0x0000000080008009,
|
||||||
|
0x000000008000000A,
|
||||||
|
0x000000008000808B,
|
||||||
|
0x800000000000008B,
|
||||||
|
0x8000000000008089,
|
||||||
|
0x8000000000008003,
|
||||||
|
0x8000000000008002,
|
||||||
|
0x8000000000000080,
|
||||||
|
0x000000000000800A,
|
||||||
|
0x800000008000000A,
|
||||||
|
0x8000000080008081,
|
||||||
|
0x8000000000008080,
|
||||||
|
0x0000000080000001,
|
||||||
|
0x8000000080008008,
|
||||||
|
}
|
||||||
|
|
||||||
|
// keccakF1600 applies the Keccak permutation to a 1600b-wide
|
||||||
|
// state represented as a slice of 25 uint64s.
|
||||||
|
func keccakF1600(a *[25]uint64) {
|
||||||
|
// Implementation translated from Keccak-inplace.c
|
||||||
|
// in the keccak reference code.
|
||||||
|
var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64
|
||||||
|
|
||||||
|
for i := 0; i < 24; i += 4 {
|
||||||
|
// Combines the 5 steps in each round into 2 steps.
|
||||||
|
// Unrolls 4 rounds per loop and spreads some steps across rounds.
|
||||||
|
|
||||||
|
// Round 1
|
||||||
|
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||||
|
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||||
|
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||||
|
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||||
|
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||||
|
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||||
|
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||||
|
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||||
|
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||||
|
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||||
|
|
||||||
|
bc0 = a[0] ^ d0
|
||||||
|
t = a[6] ^ d1
|
||||||
|
bc1 = bits.RotateLeft64(t, 44)
|
||||||
|
t = a[12] ^ d2
|
||||||
|
bc2 = bits.RotateLeft64(t, 43)
|
||||||
|
t = a[18] ^ d3
|
||||||
|
bc3 = bits.RotateLeft64(t, 21)
|
||||||
|
t = a[24] ^ d4
|
||||||
|
bc4 = bits.RotateLeft64(t, 14)
|
||||||
|
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i]
|
||||||
|
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[10] ^ d0
|
||||||
|
bc2 = bits.RotateLeft64(t, 3)
|
||||||
|
t = a[16] ^ d1
|
||||||
|
bc3 = bits.RotateLeft64(t, 45)
|
||||||
|
t = a[22] ^ d2
|
||||||
|
bc4 = bits.RotateLeft64(t, 61)
|
||||||
|
t = a[3] ^ d3
|
||||||
|
bc0 = bits.RotateLeft64(t, 28)
|
||||||
|
t = a[9] ^ d4
|
||||||
|
bc1 = bits.RotateLeft64(t, 20)
|
||||||
|
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[20] ^ d0
|
||||||
|
bc4 = bits.RotateLeft64(t, 18)
|
||||||
|
t = a[1] ^ d1
|
||||||
|
bc0 = bits.RotateLeft64(t, 1)
|
||||||
|
t = a[7] ^ d2
|
||||||
|
bc1 = bits.RotateLeft64(t, 6)
|
||||||
|
t = a[13] ^ d3
|
||||||
|
bc2 = bits.RotateLeft64(t, 25)
|
||||||
|
t = a[19] ^ d4
|
||||||
|
bc3 = bits.RotateLeft64(t, 8)
|
||||||
|
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[5] ^ d0
|
||||||
|
bc1 = bits.RotateLeft64(t, 36)
|
||||||
|
t = a[11] ^ d1
|
||||||
|
bc2 = bits.RotateLeft64(t, 10)
|
||||||
|
t = a[17] ^ d2
|
||||||
|
bc3 = bits.RotateLeft64(t, 15)
|
||||||
|
t = a[23] ^ d3
|
||||||
|
bc4 = bits.RotateLeft64(t, 56)
|
||||||
|
t = a[4] ^ d4
|
||||||
|
bc0 = bits.RotateLeft64(t, 27)
|
||||||
|
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[15] ^ d0
|
||||||
|
bc3 = bits.RotateLeft64(t, 41)
|
||||||
|
t = a[21] ^ d1
|
||||||
|
bc4 = bits.RotateLeft64(t, 2)
|
||||||
|
t = a[2] ^ d2
|
||||||
|
bc0 = bits.RotateLeft64(t, 62)
|
||||||
|
t = a[8] ^ d3
|
||||||
|
bc1 = bits.RotateLeft64(t, 55)
|
||||||
|
t = a[14] ^ d4
|
||||||
|
bc2 = bits.RotateLeft64(t, 39)
|
||||||
|
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
// Round 2
|
||||||
|
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||||
|
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||||
|
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||||
|
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||||
|
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||||
|
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||||
|
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||||
|
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||||
|
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||||
|
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||||
|
|
||||||
|
bc0 = a[0] ^ d0
|
||||||
|
t = a[16] ^ d1
|
||||||
|
bc1 = bits.RotateLeft64(t, 44)
|
||||||
|
t = a[7] ^ d2
|
||||||
|
bc2 = bits.RotateLeft64(t, 43)
|
||||||
|
t = a[23] ^ d3
|
||||||
|
bc3 = bits.RotateLeft64(t, 21)
|
||||||
|
t = a[14] ^ d4
|
||||||
|
bc4 = bits.RotateLeft64(t, 14)
|
||||||
|
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+1]
|
||||||
|
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[20] ^ d0
|
||||||
|
bc2 = bits.RotateLeft64(t, 3)
|
||||||
|
t = a[11] ^ d1
|
||||||
|
bc3 = bits.RotateLeft64(t, 45)
|
||||||
|
t = a[2] ^ d2
|
||||||
|
bc4 = bits.RotateLeft64(t, 61)
|
||||||
|
t = a[18] ^ d3
|
||||||
|
bc0 = bits.RotateLeft64(t, 28)
|
||||||
|
t = a[9] ^ d4
|
||||||
|
bc1 = bits.RotateLeft64(t, 20)
|
||||||
|
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[15] ^ d0
|
||||||
|
bc4 = bits.RotateLeft64(t, 18)
|
||||||
|
t = a[6] ^ d1
|
||||||
|
bc0 = bits.RotateLeft64(t, 1)
|
||||||
|
t = a[22] ^ d2
|
||||||
|
bc1 = bits.RotateLeft64(t, 6)
|
||||||
|
t = a[13] ^ d3
|
||||||
|
bc2 = bits.RotateLeft64(t, 25)
|
||||||
|
t = a[4] ^ d4
|
||||||
|
bc3 = bits.RotateLeft64(t, 8)
|
||||||
|
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[10] ^ d0
|
||||||
|
bc1 = bits.RotateLeft64(t, 36)
|
||||||
|
t = a[1] ^ d1
|
||||||
|
bc2 = bits.RotateLeft64(t, 10)
|
||||||
|
t = a[17] ^ d2
|
||||||
|
bc3 = bits.RotateLeft64(t, 15)
|
||||||
|
t = a[8] ^ d3
|
||||||
|
bc4 = bits.RotateLeft64(t, 56)
|
||||||
|
t = a[24] ^ d4
|
||||||
|
bc0 = bits.RotateLeft64(t, 27)
|
||||||
|
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[5] ^ d0
|
||||||
|
bc3 = bits.RotateLeft64(t, 41)
|
||||||
|
t = a[21] ^ d1
|
||||||
|
bc4 = bits.RotateLeft64(t, 2)
|
||||||
|
t = a[12] ^ d2
|
||||||
|
bc0 = bits.RotateLeft64(t, 62)
|
||||||
|
t = a[3] ^ d3
|
||||||
|
bc1 = bits.RotateLeft64(t, 55)
|
||||||
|
t = a[19] ^ d4
|
||||||
|
bc2 = bits.RotateLeft64(t, 39)
|
||||||
|
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
// Round 3
|
||||||
|
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||||
|
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||||
|
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||||
|
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||||
|
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||||
|
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||||
|
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||||
|
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||||
|
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||||
|
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||||
|
|
||||||
|
bc0 = a[0] ^ d0
|
||||||
|
t = a[11] ^ d1
|
||||||
|
bc1 = bits.RotateLeft64(t, 44)
|
||||||
|
t = a[22] ^ d2
|
||||||
|
bc2 = bits.RotateLeft64(t, 43)
|
||||||
|
t = a[8] ^ d3
|
||||||
|
bc3 = bits.RotateLeft64(t, 21)
|
||||||
|
t = a[19] ^ d4
|
||||||
|
bc4 = bits.RotateLeft64(t, 14)
|
||||||
|
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+2]
|
||||||
|
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[15] ^ d0
|
||||||
|
bc2 = bits.RotateLeft64(t, 3)
|
||||||
|
t = a[1] ^ d1
|
||||||
|
bc3 = bits.RotateLeft64(t, 45)
|
||||||
|
t = a[12] ^ d2
|
||||||
|
bc4 = bits.RotateLeft64(t, 61)
|
||||||
|
t = a[23] ^ d3
|
||||||
|
bc0 = bits.RotateLeft64(t, 28)
|
||||||
|
t = a[9] ^ d4
|
||||||
|
bc1 = bits.RotateLeft64(t, 20)
|
||||||
|
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[5] ^ d0
|
||||||
|
bc4 = bits.RotateLeft64(t, 18)
|
||||||
|
t = a[16] ^ d1
|
||||||
|
bc0 = bits.RotateLeft64(t, 1)
|
||||||
|
t = a[2] ^ d2
|
||||||
|
bc1 = bits.RotateLeft64(t, 6)
|
||||||
|
t = a[13] ^ d3
|
||||||
|
bc2 = bits.RotateLeft64(t, 25)
|
||||||
|
t = a[24] ^ d4
|
||||||
|
bc3 = bits.RotateLeft64(t, 8)
|
||||||
|
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[20] ^ d0
|
||||||
|
bc1 = bits.RotateLeft64(t, 36)
|
||||||
|
t = a[6] ^ d1
|
||||||
|
bc2 = bits.RotateLeft64(t, 10)
|
||||||
|
t = a[17] ^ d2
|
||||||
|
bc3 = bits.RotateLeft64(t, 15)
|
||||||
|
t = a[3] ^ d3
|
||||||
|
bc4 = bits.RotateLeft64(t, 56)
|
||||||
|
t = a[14] ^ d4
|
||||||
|
bc0 = bits.RotateLeft64(t, 27)
|
||||||
|
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[10] ^ d0
|
||||||
|
bc3 = bits.RotateLeft64(t, 41)
|
||||||
|
t = a[21] ^ d1
|
||||||
|
bc4 = bits.RotateLeft64(t, 2)
|
||||||
|
t = a[7] ^ d2
|
||||||
|
bc0 = bits.RotateLeft64(t, 62)
|
||||||
|
t = a[18] ^ d3
|
||||||
|
bc1 = bits.RotateLeft64(t, 55)
|
||||||
|
t = a[4] ^ d4
|
||||||
|
bc2 = bits.RotateLeft64(t, 39)
|
||||||
|
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
// Round 4
|
||||||
|
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||||
|
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||||
|
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||||
|
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||||
|
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||||
|
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||||
|
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||||
|
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||||
|
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||||
|
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||||
|
|
||||||
|
bc0 = a[0] ^ d0
|
||||||
|
t = a[1] ^ d1
|
||||||
|
bc1 = bits.RotateLeft64(t, 44)
|
||||||
|
t = a[2] ^ d2
|
||||||
|
bc2 = bits.RotateLeft64(t, 43)
|
||||||
|
t = a[3] ^ d3
|
||||||
|
bc3 = bits.RotateLeft64(t, 21)
|
||||||
|
t = a[4] ^ d4
|
||||||
|
bc4 = bits.RotateLeft64(t, 14)
|
||||||
|
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+3]
|
||||||
|
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[5] ^ d0
|
||||||
|
bc2 = bits.RotateLeft64(t, 3)
|
||||||
|
t = a[6] ^ d1
|
||||||
|
bc3 = bits.RotateLeft64(t, 45)
|
||||||
|
t = a[7] ^ d2
|
||||||
|
bc4 = bits.RotateLeft64(t, 61)
|
||||||
|
t = a[8] ^ d3
|
||||||
|
bc0 = bits.RotateLeft64(t, 28)
|
||||||
|
t = a[9] ^ d4
|
||||||
|
bc1 = bits.RotateLeft64(t, 20)
|
||||||
|
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[10] ^ d0
|
||||||
|
bc4 = bits.RotateLeft64(t, 18)
|
||||||
|
t = a[11] ^ d1
|
||||||
|
bc0 = bits.RotateLeft64(t, 1)
|
||||||
|
t = a[12] ^ d2
|
||||||
|
bc1 = bits.RotateLeft64(t, 6)
|
||||||
|
t = a[13] ^ d3
|
||||||
|
bc2 = bits.RotateLeft64(t, 25)
|
||||||
|
t = a[14] ^ d4
|
||||||
|
bc3 = bits.RotateLeft64(t, 8)
|
||||||
|
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[15] ^ d0
|
||||||
|
bc1 = bits.RotateLeft64(t, 36)
|
||||||
|
t = a[16] ^ d1
|
||||||
|
bc2 = bits.RotateLeft64(t, 10)
|
||||||
|
t = a[17] ^ d2
|
||||||
|
bc3 = bits.RotateLeft64(t, 15)
|
||||||
|
t = a[18] ^ d3
|
||||||
|
bc4 = bits.RotateLeft64(t, 56)
|
||||||
|
t = a[19] ^ d4
|
||||||
|
bc0 = bits.RotateLeft64(t, 27)
|
||||||
|
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[20] ^ d0
|
||||||
|
bc3 = bits.RotateLeft64(t, 41)
|
||||||
|
t = a[21] ^ d1
|
||||||
|
bc4 = bits.RotateLeft64(t, 2)
|
||||||
|
t = a[22] ^ d2
|
||||||
|
bc0 = bits.RotateLeft64(t, 62)
|
||||||
|
t = a[23] ^ d3
|
||||||
|
bc1 = bits.RotateLeft64(t, 55)
|
||||||
|
t = a[24] ^ d4
|
||||||
|
bc2 = bits.RotateLeft64(t, 39)
|
||||||
|
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build amd64 && !purego && gc
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// This function is implemented in keccakf_amd64.s.
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
|
func keccakF1600(a *[25]uint64)
|
|
@ -0,0 +1,390 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build amd64 && !purego && gc
|
||||||
|
|
||||||
|
// This code was translated into a form compatible with 6a from the public
|
||||||
|
// domain sources at https://github.com/gvanas/KeccakCodePackage
|
||||||
|
|
||||||
|
// Offsets in state
|
||||||
|
#define _ba (0*8)
|
||||||
|
#define _be (1*8)
|
||||||
|
#define _bi (2*8)
|
||||||
|
#define _bo (3*8)
|
||||||
|
#define _bu (4*8)
|
||||||
|
#define _ga (5*8)
|
||||||
|
#define _ge (6*8)
|
||||||
|
#define _gi (7*8)
|
||||||
|
#define _go (8*8)
|
||||||
|
#define _gu (9*8)
|
||||||
|
#define _ka (10*8)
|
||||||
|
#define _ke (11*8)
|
||||||
|
#define _ki (12*8)
|
||||||
|
#define _ko (13*8)
|
||||||
|
#define _ku (14*8)
|
||||||
|
#define _ma (15*8)
|
||||||
|
#define _me (16*8)
|
||||||
|
#define _mi (17*8)
|
||||||
|
#define _mo (18*8)
|
||||||
|
#define _mu (19*8)
|
||||||
|
#define _sa (20*8)
|
||||||
|
#define _se (21*8)
|
||||||
|
#define _si (22*8)
|
||||||
|
#define _so (23*8)
|
||||||
|
#define _su (24*8)
|
||||||
|
|
||||||
|
// Temporary registers
|
||||||
|
#define rT1 AX
|
||||||
|
|
||||||
|
// Round vars
|
||||||
|
#define rpState DI
|
||||||
|
#define rpStack SP
|
||||||
|
|
||||||
|
#define rDa BX
|
||||||
|
#define rDe CX
|
||||||
|
#define rDi DX
|
||||||
|
#define rDo R8
|
||||||
|
#define rDu R9
|
||||||
|
|
||||||
|
#define rBa R10
|
||||||
|
#define rBe R11
|
||||||
|
#define rBi R12
|
||||||
|
#define rBo R13
|
||||||
|
#define rBu R14
|
||||||
|
|
||||||
|
#define rCa SI
|
||||||
|
#define rCe BP
|
||||||
|
#define rCi rBi
|
||||||
|
#define rCo rBo
|
||||||
|
#define rCu R15
|
||||||
|
|
||||||
|
#define MOVQ_RBI_RCE MOVQ rBi, rCe
|
||||||
|
#define XORQ_RT1_RCA XORQ rT1, rCa
|
||||||
|
#define XORQ_RT1_RCE XORQ rT1, rCe
|
||||||
|
#define XORQ_RBA_RCU XORQ rBa, rCu
|
||||||
|
#define XORQ_RBE_RCU XORQ rBe, rCu
|
||||||
|
#define XORQ_RDU_RCU XORQ rDu, rCu
|
||||||
|
#define XORQ_RDA_RCA XORQ rDa, rCa
|
||||||
|
#define XORQ_RDE_RCE XORQ rDe, rCe
|
||||||
|
|
||||||
|
#define mKeccakRound(iState, oState, rc, B_RBI_RCE, G_RT1_RCA, G_RT1_RCE, G_RBA_RCU, K_RT1_RCA, K_RT1_RCE, K_RBA_RCU, M_RT1_RCA, M_RT1_RCE, M_RBE_RCU, S_RDU_RCU, S_RDA_RCA, S_RDE_RCE) \
|
||||||
|
/* Prepare round */ \
|
||||||
|
MOVQ rCe, rDa; \
|
||||||
|
ROLQ $1, rDa; \
|
||||||
|
\
|
||||||
|
MOVQ _bi(iState), rCi; \
|
||||||
|
XORQ _gi(iState), rDi; \
|
||||||
|
XORQ rCu, rDa; \
|
||||||
|
XORQ _ki(iState), rCi; \
|
||||||
|
XORQ _mi(iState), rDi; \
|
||||||
|
XORQ rDi, rCi; \
|
||||||
|
\
|
||||||
|
MOVQ rCi, rDe; \
|
||||||
|
ROLQ $1, rDe; \
|
||||||
|
\
|
||||||
|
MOVQ _bo(iState), rCo; \
|
||||||
|
XORQ _go(iState), rDo; \
|
||||||
|
XORQ rCa, rDe; \
|
||||||
|
XORQ _ko(iState), rCo; \
|
||||||
|
XORQ _mo(iState), rDo; \
|
||||||
|
XORQ rDo, rCo; \
|
||||||
|
\
|
||||||
|
MOVQ rCo, rDi; \
|
||||||
|
ROLQ $1, rDi; \
|
||||||
|
\
|
||||||
|
MOVQ rCu, rDo; \
|
||||||
|
XORQ rCe, rDi; \
|
||||||
|
ROLQ $1, rDo; \
|
||||||
|
\
|
||||||
|
MOVQ rCa, rDu; \
|
||||||
|
XORQ rCi, rDo; \
|
||||||
|
ROLQ $1, rDu; \
|
||||||
|
\
|
||||||
|
/* Result b */ \
|
||||||
|
MOVQ _ba(iState), rBa; \
|
||||||
|
MOVQ _ge(iState), rBe; \
|
||||||
|
XORQ rCo, rDu; \
|
||||||
|
MOVQ _ki(iState), rBi; \
|
||||||
|
MOVQ _mo(iState), rBo; \
|
||||||
|
MOVQ _su(iState), rBu; \
|
||||||
|
XORQ rDe, rBe; \
|
||||||
|
ROLQ $44, rBe; \
|
||||||
|
XORQ rDi, rBi; \
|
||||||
|
XORQ rDa, rBa; \
|
||||||
|
ROLQ $43, rBi; \
|
||||||
|
\
|
||||||
|
MOVQ rBe, rCa; \
|
||||||
|
MOVQ rc, rT1; \
|
||||||
|
ORQ rBi, rCa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
XORQ rT1, rCa; \
|
||||||
|
MOVQ rCa, _ba(oState); \
|
||||||
|
\
|
||||||
|
XORQ rDu, rBu; \
|
||||||
|
ROLQ $14, rBu; \
|
||||||
|
MOVQ rBa, rCu; \
|
||||||
|
ANDQ rBe, rCu; \
|
||||||
|
XORQ rBu, rCu; \
|
||||||
|
MOVQ rCu, _bu(oState); \
|
||||||
|
\
|
||||||
|
XORQ rDo, rBo; \
|
||||||
|
ROLQ $21, rBo; \
|
||||||
|
MOVQ rBo, rT1; \
|
||||||
|
ANDQ rBu, rT1; \
|
||||||
|
XORQ rBi, rT1; \
|
||||||
|
MOVQ rT1, _bi(oState); \
|
||||||
|
\
|
||||||
|
NOTQ rBi; \
|
||||||
|
ORQ rBa, rBu; \
|
||||||
|
ORQ rBo, rBi; \
|
||||||
|
XORQ rBo, rBu; \
|
||||||
|
XORQ rBe, rBi; \
|
||||||
|
MOVQ rBu, _bo(oState); \
|
||||||
|
MOVQ rBi, _be(oState); \
|
||||||
|
B_RBI_RCE; \
|
||||||
|
\
|
||||||
|
/* Result g */ \
|
||||||
|
MOVQ _gu(iState), rBe; \
|
||||||
|
XORQ rDu, rBe; \
|
||||||
|
MOVQ _ka(iState), rBi; \
|
||||||
|
ROLQ $20, rBe; \
|
||||||
|
XORQ rDa, rBi; \
|
||||||
|
ROLQ $3, rBi; \
|
||||||
|
MOVQ _bo(iState), rBa; \
|
||||||
|
MOVQ rBe, rT1; \
|
||||||
|
ORQ rBi, rT1; \
|
||||||
|
XORQ rDo, rBa; \
|
||||||
|
MOVQ _me(iState), rBo; \
|
||||||
|
MOVQ _si(iState), rBu; \
|
||||||
|
ROLQ $28, rBa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
MOVQ rT1, _ga(oState); \
|
||||||
|
G_RT1_RCA; \
|
||||||
|
\
|
||||||
|
XORQ rDe, rBo; \
|
||||||
|
ROLQ $45, rBo; \
|
||||||
|
MOVQ rBi, rT1; \
|
||||||
|
ANDQ rBo, rT1; \
|
||||||
|
XORQ rBe, rT1; \
|
||||||
|
MOVQ rT1, _ge(oState); \
|
||||||
|
G_RT1_RCE; \
|
||||||
|
\
|
||||||
|
XORQ rDi, rBu; \
|
||||||
|
ROLQ $61, rBu; \
|
||||||
|
MOVQ rBu, rT1; \
|
||||||
|
ORQ rBa, rT1; \
|
||||||
|
XORQ rBo, rT1; \
|
||||||
|
MOVQ rT1, _go(oState); \
|
||||||
|
\
|
||||||
|
ANDQ rBe, rBa; \
|
||||||
|
XORQ rBu, rBa; \
|
||||||
|
MOVQ rBa, _gu(oState); \
|
||||||
|
NOTQ rBu; \
|
||||||
|
G_RBA_RCU; \
|
||||||
|
\
|
||||||
|
ORQ rBu, rBo; \
|
||||||
|
XORQ rBi, rBo; \
|
||||||
|
MOVQ rBo, _gi(oState); \
|
||||||
|
\
|
||||||
|
/* Result k */ \
|
||||||
|
MOVQ _be(iState), rBa; \
|
||||||
|
MOVQ _gi(iState), rBe; \
|
||||||
|
MOVQ _ko(iState), rBi; \
|
||||||
|
MOVQ _mu(iState), rBo; \
|
||||||
|
MOVQ _sa(iState), rBu; \
|
||||||
|
XORQ rDi, rBe; \
|
||||||
|
ROLQ $6, rBe; \
|
||||||
|
XORQ rDo, rBi; \
|
||||||
|
ROLQ $25, rBi; \
|
||||||
|
MOVQ rBe, rT1; \
|
||||||
|
ORQ rBi, rT1; \
|
||||||
|
XORQ rDe, rBa; \
|
||||||
|
ROLQ $1, rBa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
MOVQ rT1, _ka(oState); \
|
||||||
|
K_RT1_RCA; \
|
||||||
|
\
|
||||||
|
XORQ rDu, rBo; \
|
||||||
|
ROLQ $8, rBo; \
|
||||||
|
MOVQ rBi, rT1; \
|
||||||
|
ANDQ rBo, rT1; \
|
||||||
|
XORQ rBe, rT1; \
|
||||||
|
MOVQ rT1, _ke(oState); \
|
||||||
|
K_RT1_RCE; \
|
||||||
|
\
|
||||||
|
XORQ rDa, rBu; \
|
||||||
|
ROLQ $18, rBu; \
|
||||||
|
NOTQ rBo; \
|
||||||
|
MOVQ rBo, rT1; \
|
||||||
|
ANDQ rBu, rT1; \
|
||||||
|
XORQ rBi, rT1; \
|
||||||
|
MOVQ rT1, _ki(oState); \
|
||||||
|
\
|
||||||
|
MOVQ rBu, rT1; \
|
||||||
|
ORQ rBa, rT1; \
|
||||||
|
XORQ rBo, rT1; \
|
||||||
|
MOVQ rT1, _ko(oState); \
|
||||||
|
\
|
||||||
|
ANDQ rBe, rBa; \
|
||||||
|
XORQ rBu, rBa; \
|
||||||
|
MOVQ rBa, _ku(oState); \
|
||||||
|
K_RBA_RCU; \
|
||||||
|
\
|
||||||
|
/* Result m */ \
|
||||||
|
MOVQ _ga(iState), rBe; \
|
||||||
|
XORQ rDa, rBe; \
|
||||||
|
MOVQ _ke(iState), rBi; \
|
||||||
|
ROLQ $36, rBe; \
|
||||||
|
XORQ rDe, rBi; \
|
||||||
|
MOVQ _bu(iState), rBa; \
|
||||||
|
ROLQ $10, rBi; \
|
||||||
|
MOVQ rBe, rT1; \
|
||||||
|
MOVQ _mi(iState), rBo; \
|
||||||
|
ANDQ rBi, rT1; \
|
||||||
|
XORQ rDu, rBa; \
|
||||||
|
MOVQ _so(iState), rBu; \
|
||||||
|
ROLQ $27, rBa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
MOVQ rT1, _ma(oState); \
|
||||||
|
M_RT1_RCA; \
|
||||||
|
\
|
||||||
|
XORQ rDi, rBo; \
|
||||||
|
ROLQ $15, rBo; \
|
||||||
|
MOVQ rBi, rT1; \
|
||||||
|
ORQ rBo, rT1; \
|
||||||
|
XORQ rBe, rT1; \
|
||||||
|
MOVQ rT1, _me(oState); \
|
||||||
|
M_RT1_RCE; \
|
||||||
|
\
|
||||||
|
XORQ rDo, rBu; \
|
||||||
|
ROLQ $56, rBu; \
|
||||||
|
NOTQ rBo; \
|
||||||
|
MOVQ rBo, rT1; \
|
||||||
|
ORQ rBu, rT1; \
|
||||||
|
XORQ rBi, rT1; \
|
||||||
|
MOVQ rT1, _mi(oState); \
|
||||||
|
\
|
||||||
|
ORQ rBa, rBe; \
|
||||||
|
XORQ rBu, rBe; \
|
||||||
|
MOVQ rBe, _mu(oState); \
|
||||||
|
\
|
||||||
|
ANDQ rBa, rBu; \
|
||||||
|
XORQ rBo, rBu; \
|
||||||
|
MOVQ rBu, _mo(oState); \
|
||||||
|
M_RBE_RCU; \
|
||||||
|
\
|
||||||
|
/* Result s */ \
|
||||||
|
MOVQ _bi(iState), rBa; \
|
||||||
|
MOVQ _go(iState), rBe; \
|
||||||
|
MOVQ _ku(iState), rBi; \
|
||||||
|
XORQ rDi, rBa; \
|
||||||
|
MOVQ _ma(iState), rBo; \
|
||||||
|
ROLQ $62, rBa; \
|
||||||
|
XORQ rDo, rBe; \
|
||||||
|
MOVQ _se(iState), rBu; \
|
||||||
|
ROLQ $55, rBe; \
|
||||||
|
\
|
||||||
|
XORQ rDu, rBi; \
|
||||||
|
MOVQ rBa, rDu; \
|
||||||
|
XORQ rDe, rBu; \
|
||||||
|
ROLQ $2, rBu; \
|
||||||
|
ANDQ rBe, rDu; \
|
||||||
|
XORQ rBu, rDu; \
|
||||||
|
MOVQ rDu, _su(oState); \
|
||||||
|
\
|
||||||
|
ROLQ $39, rBi; \
|
||||||
|
S_RDU_RCU; \
|
||||||
|
NOTQ rBe; \
|
||||||
|
XORQ rDa, rBo; \
|
||||||
|
MOVQ rBe, rDa; \
|
||||||
|
ANDQ rBi, rDa; \
|
||||||
|
XORQ rBa, rDa; \
|
||||||
|
MOVQ rDa, _sa(oState); \
|
||||||
|
S_RDA_RCA; \
|
||||||
|
\
|
||||||
|
ROLQ $41, rBo; \
|
||||||
|
MOVQ rBi, rDe; \
|
||||||
|
ORQ rBo, rDe; \
|
||||||
|
XORQ rBe, rDe; \
|
||||||
|
MOVQ rDe, _se(oState); \
|
||||||
|
S_RDE_RCE; \
|
||||||
|
\
|
||||||
|
MOVQ rBo, rDi; \
|
||||||
|
MOVQ rBu, rDo; \
|
||||||
|
ANDQ rBu, rDi; \
|
||||||
|
ORQ rBa, rDo; \
|
||||||
|
XORQ rBi, rDi; \
|
||||||
|
XORQ rBo, rDo; \
|
||||||
|
MOVQ rDi, _si(oState); \
|
||||||
|
MOVQ rDo, _so(oState) \
|
||||||
|
|
||||||
|
// func keccakF1600(a *[25]uint64)
|
||||||
|
TEXT ·keccakF1600(SB), 0, $200-8
|
||||||
|
MOVQ a+0(FP), rpState
|
||||||
|
|
||||||
|
// Convert the user state into an internal state
|
||||||
|
NOTQ _be(rpState)
|
||||||
|
NOTQ _bi(rpState)
|
||||||
|
NOTQ _go(rpState)
|
||||||
|
NOTQ _ki(rpState)
|
||||||
|
NOTQ _mi(rpState)
|
||||||
|
NOTQ _sa(rpState)
|
||||||
|
|
||||||
|
// Execute the KeccakF permutation
|
||||||
|
MOVQ _ba(rpState), rCa
|
||||||
|
MOVQ _be(rpState), rCe
|
||||||
|
MOVQ _bu(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _ga(rpState), rCa
|
||||||
|
XORQ _ge(rpState), rCe
|
||||||
|
XORQ _gu(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _ka(rpState), rCa
|
||||||
|
XORQ _ke(rpState), rCe
|
||||||
|
XORQ _ku(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _ma(rpState), rCa
|
||||||
|
XORQ _me(rpState), rCe
|
||||||
|
XORQ _mu(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _sa(rpState), rCa
|
||||||
|
XORQ _se(rpState), rCe
|
||||||
|
MOVQ _si(rpState), rDi
|
||||||
|
MOVQ _so(rpState), rDo
|
||||||
|
XORQ _su(rpState), rCu
|
||||||
|
|
||||||
|
mKeccakRound(rpState, rpStack, $0x0000000000000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x0000000000008082, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x800000000000808a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000080008000, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000000000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000000000008a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x0000000000000088, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x0000000080008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x000000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000008000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x800000000000008b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000000008089, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000008003, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000000008002, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000000080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000000000800a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x800000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000008080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000080008008, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP)
|
||||||
|
|
||||||
|
// Revert the internal state to the user state
|
||||||
|
NOTQ _be(rpState)
|
||||||
|
NOTQ _bi(rpState)
|
||||||
|
NOTQ _go(rpState)
|
||||||
|
NOTQ _ki(rpState)
|
||||||
|
NOTQ _mi(rpState)
|
||||||
|
NOTQ _sa(rpState)
|
||||||
|
|
||||||
|
RET
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.4
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
crypto.RegisterHash(crypto.SHA3_224, New224)
|
||||||
|
crypto.RegisterHash(crypto.SHA3_256, New256)
|
||||||
|
crypto.RegisterHash(crypto.SHA3_384, New384)
|
||||||
|
crypto.RegisterHash(crypto.SHA3_512, New512)
|
||||||
|
}
|
|
@ -0,0 +1,197 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// spongeDirection indicates the direction bytes are flowing through the sponge.
|
||||||
|
type spongeDirection int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// spongeAbsorbing indicates that the sponge is absorbing input.
|
||||||
|
spongeAbsorbing spongeDirection = iota
|
||||||
|
// spongeSqueezing indicates that the sponge is being squeezed.
|
||||||
|
spongeSqueezing
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// maxRate is the maximum size of the internal buffer. SHAKE-256
|
||||||
|
// currently needs the largest buffer.
|
||||||
|
maxRate = 168
|
||||||
|
)
|
||||||
|
|
||||||
|
type state struct {
|
||||||
|
// Generic sponge components.
|
||||||
|
a [25]uint64 // main state of the hash
|
||||||
|
buf []byte // points into storage
|
||||||
|
rate int // the number of bytes of state to use
|
||||||
|
|
||||||
|
// dsbyte contains the "domain separation" bits and the first bit of
|
||||||
|
// the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
|
||||||
|
// SHA-3 and SHAKE functions by appending bitstrings to the message.
|
||||||
|
// Using a little-endian bit-ordering convention, these are "01" for SHA-3
|
||||||
|
// and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
|
||||||
|
// padding rule from section 5.1 is applied to pad the message to a multiple
|
||||||
|
// of the rate, which involves adding a "1" bit, zero or more "0" bits, and
|
||||||
|
// a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
|
||||||
|
// giving 00000110b (0x06) and 00011111b (0x1f).
|
||||||
|
// [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
|
||||||
|
// "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
|
||||||
|
// Extendable-Output Functions (May 2014)"
|
||||||
|
dsbyte byte
|
||||||
|
|
||||||
|
storage storageBuf
|
||||||
|
|
||||||
|
// Specific to SHA-3 and SHAKE.
|
||||||
|
outputLen int // the default output size in bytes
|
||||||
|
state spongeDirection // whether the sponge is absorbing or squeezing
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockSize returns the rate of sponge underlying this hash function.
|
||||||
|
func (d *state) BlockSize() int { return d.rate }
|
||||||
|
|
||||||
|
// Size returns the output size of the hash function in bytes.
|
||||||
|
func (d *state) Size() int { return d.outputLen }
|
||||||
|
|
||||||
|
// Reset clears the internal state by zeroing the sponge state and
|
||||||
|
// the byte buffer, and setting Sponge.state to absorbing.
|
||||||
|
func (d *state) Reset() {
|
||||||
|
// Zero the permutation's state.
|
||||||
|
for i := range d.a {
|
||||||
|
d.a[i] = 0
|
||||||
|
}
|
||||||
|
d.state = spongeAbsorbing
|
||||||
|
d.buf = d.storage.asBytes()[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *state) clone() *state {
|
||||||
|
ret := *d
|
||||||
|
if ret.state == spongeAbsorbing {
|
||||||
|
ret.buf = ret.storage.asBytes()[:len(ret.buf)]
|
||||||
|
} else {
|
||||||
|
ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate]
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// permute applies the KeccakF-1600 permutation. It handles
|
||||||
|
// any input-output buffering.
|
||||||
|
func (d *state) permute() {
|
||||||
|
switch d.state {
|
||||||
|
case spongeAbsorbing:
|
||||||
|
// If we're absorbing, we need to xor the input into the state
|
||||||
|
// before applying the permutation.
|
||||||
|
xorIn(d, d.buf)
|
||||||
|
d.buf = d.storage.asBytes()[:0]
|
||||||
|
keccakF1600(&d.a)
|
||||||
|
case spongeSqueezing:
|
||||||
|
// If we're squeezing, we need to apply the permutation before
|
||||||
|
// copying more output.
|
||||||
|
keccakF1600(&d.a)
|
||||||
|
d.buf = d.storage.asBytes()[:d.rate]
|
||||||
|
copyOut(d, d.buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pads appends the domain separation bits in dsbyte, applies
|
||||||
|
// the multi-bitrate 10..1 padding rule, and permutes the state.
|
||||||
|
func (d *state) padAndPermute(dsbyte byte) {
|
||||||
|
if d.buf == nil {
|
||||||
|
d.buf = d.storage.asBytes()[:0]
|
||||||
|
}
|
||||||
|
// Pad with this instance's domain-separator bits. We know that there's
|
||||||
|
// at least one byte of space in d.buf because, if it were full,
|
||||||
|
// permute would have been called to empty it. dsbyte also contains the
|
||||||
|
// first one bit for the padding. See the comment in the state struct.
|
||||||
|
d.buf = append(d.buf, dsbyte)
|
||||||
|
zerosStart := len(d.buf)
|
||||||
|
d.buf = d.storage.asBytes()[:d.rate]
|
||||||
|
for i := zerosStart; i < d.rate; i++ {
|
||||||
|
d.buf[i] = 0
|
||||||
|
}
|
||||||
|
// This adds the final one bit for the padding. Because of the way that
|
||||||
|
// bits are numbered from the LSB upwards, the final bit is the MSB of
|
||||||
|
// the last byte.
|
||||||
|
d.buf[d.rate-1] ^= 0x80
|
||||||
|
// Apply the permutation
|
||||||
|
d.permute()
|
||||||
|
d.state = spongeSqueezing
|
||||||
|
d.buf = d.storage.asBytes()[:d.rate]
|
||||||
|
copyOut(d, d.buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write absorbs more data into the hash's state. It panics if any
|
||||||
|
// output has already been read.
|
||||||
|
func (d *state) Write(p []byte) (written int, err error) {
|
||||||
|
if d.state != spongeAbsorbing {
|
||||||
|
panic("sha3: Write after Read")
|
||||||
|
}
|
||||||
|
if d.buf == nil {
|
||||||
|
d.buf = d.storage.asBytes()[:0]
|
||||||
|
}
|
||||||
|
written = len(p)
|
||||||
|
|
||||||
|
for len(p) > 0 {
|
||||||
|
if len(d.buf) == 0 && len(p) >= d.rate {
|
||||||
|
// The fast path; absorb a full "rate" bytes of input and apply the permutation.
|
||||||
|
xorIn(d, p[:d.rate])
|
||||||
|
p = p[d.rate:]
|
||||||
|
keccakF1600(&d.a)
|
||||||
|
} else {
|
||||||
|
// The slow path; buffer the input until we can fill the sponge, and then xor it in.
|
||||||
|
todo := d.rate - len(d.buf)
|
||||||
|
if todo > len(p) {
|
||||||
|
todo = len(p)
|
||||||
|
}
|
||||||
|
d.buf = append(d.buf, p[:todo]...)
|
||||||
|
p = p[todo:]
|
||||||
|
|
||||||
|
// If the sponge is full, apply the permutation.
|
||||||
|
if len(d.buf) == d.rate {
|
||||||
|
d.permute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read squeezes an arbitrary number of bytes from the sponge.
|
||||||
|
func (d *state) Read(out []byte) (n int, err error) {
|
||||||
|
// If we're still absorbing, pad and apply the permutation.
|
||||||
|
if d.state == spongeAbsorbing {
|
||||||
|
d.padAndPermute(d.dsbyte)
|
||||||
|
}
|
||||||
|
|
||||||
|
n = len(out)
|
||||||
|
|
||||||
|
// Now, do the squeezing.
|
||||||
|
for len(out) > 0 {
|
||||||
|
n := copy(out, d.buf)
|
||||||
|
d.buf = d.buf[n:]
|
||||||
|
out = out[n:]
|
||||||
|
|
||||||
|
// Apply the permutation if we've squeezed the sponge dry.
|
||||||
|
if len(d.buf) == 0 {
|
||||||
|
d.permute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum applies padding to the hash state and then squeezes out the desired
|
||||||
|
// number of output bytes. It panics if any output has already been read.
|
||||||
|
func (d *state) Sum(in []byte) []byte {
|
||||||
|
if d.state != spongeAbsorbing {
|
||||||
|
panic("sha3: Sum after Read")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a copy of the original hash so that caller can keep writing
|
||||||
|
// and summing.
|
||||||
|
dup := d.clone()
|
||||||
|
hash := make([]byte, dup.outputLen, 64) // explicit cap to allow stack allocation
|
||||||
|
dup.Read(hash)
|
||||||
|
return append(in, hash...)
|
||||||
|
}
|
|
@ -0,0 +1,288 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gc && !purego
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// This file contains code for using the 'compute intermediate
|
||||||
|
// message digest' (KIMD) and 'compute last message digest' (KLMD)
|
||||||
|
// instructions to compute SHA-3 and SHAKE hashes on IBM Z.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash"
|
||||||
|
|
||||||
|
"golang.org/x/sys/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
// codes represent 7-bit KIMD/KLMD function codes as defined in
|
||||||
|
// the Principles of Operation.
|
||||||
|
type code uint64
|
||||||
|
|
||||||
|
const (
|
||||||
|
// function codes for KIMD/KLMD
|
||||||
|
sha3_224 code = 32
|
||||||
|
sha3_256 = 33
|
||||||
|
sha3_384 = 34
|
||||||
|
sha3_512 = 35
|
||||||
|
shake_128 = 36
|
||||||
|
shake_256 = 37
|
||||||
|
nopad = 0x100
|
||||||
|
)
|
||||||
|
|
||||||
|
// kimd is a wrapper for the 'compute intermediate message digest' instruction.
|
||||||
|
// src must be a multiple of the rate for the given function code.
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func kimd(function code, chain *[200]byte, src []byte)
|
||||||
|
|
||||||
|
// klmd is a wrapper for the 'compute last message digest' instruction.
|
||||||
|
// src padding is handled by the instruction.
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func klmd(function code, chain *[200]byte, dst, src []byte)
|
||||||
|
|
||||||
|
type asmState struct {
|
||||||
|
a [200]byte // 1600 bit state
|
||||||
|
buf []byte // care must be taken to ensure cap(buf) is a multiple of rate
|
||||||
|
rate int // equivalent to block size
|
||||||
|
storage [3072]byte // underlying storage for buf
|
||||||
|
outputLen int // output length for full security
|
||||||
|
function code // KIMD/KLMD function code
|
||||||
|
state spongeDirection // whether the sponge is absorbing or squeezing
|
||||||
|
}
|
||||||
|
|
||||||
|
func newAsmState(function code) *asmState {
|
||||||
|
var s asmState
|
||||||
|
s.function = function
|
||||||
|
switch function {
|
||||||
|
case sha3_224:
|
||||||
|
s.rate = 144
|
||||||
|
s.outputLen = 28
|
||||||
|
case sha3_256:
|
||||||
|
s.rate = 136
|
||||||
|
s.outputLen = 32
|
||||||
|
case sha3_384:
|
||||||
|
s.rate = 104
|
||||||
|
s.outputLen = 48
|
||||||
|
case sha3_512:
|
||||||
|
s.rate = 72
|
||||||
|
s.outputLen = 64
|
||||||
|
case shake_128:
|
||||||
|
s.rate = 168
|
||||||
|
s.outputLen = 32
|
||||||
|
case shake_256:
|
||||||
|
s.rate = 136
|
||||||
|
s.outputLen = 64
|
||||||
|
default:
|
||||||
|
panic("sha3: unrecognized function code")
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit s.buf size to a multiple of s.rate
|
||||||
|
s.resetBuf()
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *asmState) clone() *asmState {
|
||||||
|
c := *s
|
||||||
|
c.buf = c.storage[:len(s.buf):cap(s.buf)]
|
||||||
|
return &c
|
||||||
|
}
|
||||||
|
|
||||||
|
// copyIntoBuf copies b into buf. It will panic if there is not enough space to
|
||||||
|
// store all of b.
|
||||||
|
func (s *asmState) copyIntoBuf(b []byte) {
|
||||||
|
bufLen := len(s.buf)
|
||||||
|
s.buf = s.buf[:len(s.buf)+len(b)]
|
||||||
|
copy(s.buf[bufLen:], b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resetBuf points buf at storage, sets the length to 0 and sets cap to be a
|
||||||
|
// multiple of the rate.
|
||||||
|
func (s *asmState) resetBuf() {
|
||||||
|
max := (cap(s.storage) / s.rate) * s.rate
|
||||||
|
s.buf = s.storage[:0:max]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write (via the embedded io.Writer interface) adds more data to the running hash.
|
||||||
|
// It never returns an error.
|
||||||
|
func (s *asmState) Write(b []byte) (int, error) {
|
||||||
|
if s.state != spongeAbsorbing {
|
||||||
|
panic("sha3: Write after Read")
|
||||||
|
}
|
||||||
|
length := len(b)
|
||||||
|
for len(b) > 0 {
|
||||||
|
if len(s.buf) == 0 && len(b) >= cap(s.buf) {
|
||||||
|
// Hash the data directly and push any remaining bytes
|
||||||
|
// into the buffer.
|
||||||
|
remainder := len(b) % s.rate
|
||||||
|
kimd(s.function, &s.a, b[:len(b)-remainder])
|
||||||
|
if remainder != 0 {
|
||||||
|
s.copyIntoBuf(b[len(b)-remainder:])
|
||||||
|
}
|
||||||
|
return length, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s.buf) == cap(s.buf) {
|
||||||
|
// flush the buffer
|
||||||
|
kimd(s.function, &s.a, s.buf)
|
||||||
|
s.buf = s.buf[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy as much as we can into the buffer
|
||||||
|
n := len(b)
|
||||||
|
if len(b) > cap(s.buf)-len(s.buf) {
|
||||||
|
n = cap(s.buf) - len(s.buf)
|
||||||
|
}
|
||||||
|
s.copyIntoBuf(b[:n])
|
||||||
|
b = b[n:]
|
||||||
|
}
|
||||||
|
return length, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read squeezes an arbitrary number of bytes from the sponge.
|
||||||
|
func (s *asmState) Read(out []byte) (n int, err error) {
|
||||||
|
n = len(out)
|
||||||
|
|
||||||
|
// need to pad if we were absorbing
|
||||||
|
if s.state == spongeAbsorbing {
|
||||||
|
s.state = spongeSqueezing
|
||||||
|
|
||||||
|
// write hash directly into out if possible
|
||||||
|
if len(out)%s.rate == 0 {
|
||||||
|
klmd(s.function, &s.a, out, s.buf) // len(out) may be 0
|
||||||
|
s.buf = s.buf[:0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// write hash into buffer
|
||||||
|
max := cap(s.buf)
|
||||||
|
if max > len(out) {
|
||||||
|
max = (len(out)/s.rate)*s.rate + s.rate
|
||||||
|
}
|
||||||
|
klmd(s.function, &s.a, s.buf[:max], s.buf)
|
||||||
|
s.buf = s.buf[:max]
|
||||||
|
}
|
||||||
|
|
||||||
|
for len(out) > 0 {
|
||||||
|
// flush the buffer
|
||||||
|
if len(s.buf) != 0 {
|
||||||
|
c := copy(out, s.buf)
|
||||||
|
out = out[c:]
|
||||||
|
s.buf = s.buf[c:]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// write hash directly into out if possible
|
||||||
|
if len(out)%s.rate == 0 {
|
||||||
|
klmd(s.function|nopad, &s.a, out, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// write hash into buffer
|
||||||
|
s.resetBuf()
|
||||||
|
if cap(s.buf) > len(out) {
|
||||||
|
s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate]
|
||||||
|
}
|
||||||
|
klmd(s.function|nopad, &s.a, s.buf, nil)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum appends the current hash to b and returns the resulting slice.
|
||||||
|
// It does not change the underlying hash state.
|
||||||
|
func (s *asmState) Sum(b []byte) []byte {
|
||||||
|
if s.state != spongeAbsorbing {
|
||||||
|
panic("sha3: Sum after Read")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the state to preserve the original.
|
||||||
|
a := s.a
|
||||||
|
|
||||||
|
// Hash the buffer. Note that we don't clear it because we
|
||||||
|
// aren't updating the state.
|
||||||
|
klmd(s.function, &a, nil, s.buf)
|
||||||
|
return append(b, a[:s.outputLen]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset resets the Hash to its initial state.
|
||||||
|
func (s *asmState) Reset() {
|
||||||
|
for i := range s.a {
|
||||||
|
s.a[i] = 0
|
||||||
|
}
|
||||||
|
s.resetBuf()
|
||||||
|
s.state = spongeAbsorbing
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size returns the number of bytes Sum will return.
|
||||||
|
func (s *asmState) Size() int {
|
||||||
|
return s.outputLen
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockSize returns the hash's underlying block size.
|
||||||
|
// The Write method must be able to accept any amount
|
||||||
|
// of data, but it may operate more efficiently if all writes
|
||||||
|
// are a multiple of the block size.
|
||||||
|
func (s *asmState) BlockSize() int {
|
||||||
|
return s.rate
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns a copy of the ShakeHash in its current state.
|
||||||
|
func (s *asmState) Clone() ShakeHash {
|
||||||
|
return s.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
// new224Asm returns an assembly implementation of SHA3-224 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new224Asm() hash.Hash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(sha3_224)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// new256Asm returns an assembly implementation of SHA3-256 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new256Asm() hash.Hash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(sha3_256)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// new384Asm returns an assembly implementation of SHA3-384 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new384Asm() hash.Hash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(sha3_384)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// new512Asm returns an assembly implementation of SHA3-512 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new512Asm() hash.Hash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(sha3_512)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func newShake128Asm() ShakeHash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(shake_128)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func newShake256Asm() ShakeHash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(shake_256)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gc && !purego
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// func kimd(function code, chain *[200]byte, src []byte)
|
||||||
|
TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40
|
||||||
|
MOVD function+0(FP), R0
|
||||||
|
MOVD chain+8(FP), R1
|
||||||
|
LMG src+16(FP), R2, R3 // R2=base, R3=len
|
||||||
|
|
||||||
|
continue:
|
||||||
|
WORD $0xB93E0002 // KIMD --, R2
|
||||||
|
BVS continue // continue if interrupted
|
||||||
|
MOVD $0, R0 // reset R0 for pre-go1.8 compilers
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func klmd(function code, chain *[200]byte, dst, src []byte)
|
||||||
|
TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64
|
||||||
|
// TODO: SHAKE support
|
||||||
|
MOVD function+0(FP), R0
|
||||||
|
MOVD chain+8(FP), R1
|
||||||
|
LMG dst+16(FP), R2, R3 // R2=base, R3=len
|
||||||
|
LMG src+40(FP), R4, R5 // R4=base, R5=len
|
||||||
|
|
||||||
|
continue:
|
||||||
|
WORD $0xB93F0024 // KLMD R2, R4
|
||||||
|
BVS continue // continue if interrupted
|
||||||
|
MOVD $0, R0 // reset R0 for pre-go1.8 compilers
|
||||||
|
RET
|
|
@ -0,0 +1,172 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// This file defines the ShakeHash interface, and provides
|
||||||
|
// functions for creating SHAKE and cSHAKE instances, as well as utility
|
||||||
|
// functions for hashing bytes to arbitrary-length output.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// SHAKE implementation is based on FIPS PUB 202 [1]
|
||||||
|
// cSHAKE implementations is based on NIST SP 800-185 [2]
|
||||||
|
//
|
||||||
|
// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
|
||||||
|
// [2] https://doi.org/10.6028/NIST.SP.800-185
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ShakeHash defines the interface to hash functions that support
|
||||||
|
// arbitrary-length output. When used as a plain [hash.Hash], it
|
||||||
|
// produces minimum-length outputs that provide full-strength generic
|
||||||
|
// security.
|
||||||
|
type ShakeHash interface {
|
||||||
|
hash.Hash
|
||||||
|
|
||||||
|
// Read reads more output from the hash; reading affects the hash's
|
||||||
|
// state. (ShakeHash.Read is thus very different from Hash.Sum)
|
||||||
|
// It never returns an error, but subsequent calls to Write or Sum
|
||||||
|
// will panic.
|
||||||
|
io.Reader
|
||||||
|
|
||||||
|
// Clone returns a copy of the ShakeHash in its current state.
|
||||||
|
Clone() ShakeHash
|
||||||
|
}
|
||||||
|
|
||||||
|
// cSHAKE specific context
|
||||||
|
type cshakeState struct {
|
||||||
|
*state // SHA-3 state context and Read/Write operations
|
||||||
|
|
||||||
|
// initBlock is the cSHAKE specific initialization set of bytes. It is initialized
|
||||||
|
// by newCShake function and stores concatenation of N followed by S, encoded
|
||||||
|
// by the method specified in 3.3 of [1].
|
||||||
|
// It is stored here in order for Reset() to be able to put context into
|
||||||
|
// initial state.
|
||||||
|
initBlock []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consts for configuring initial SHA-3 state
|
||||||
|
const (
|
||||||
|
dsbyteShake = 0x1f
|
||||||
|
dsbyteCShake = 0x04
|
||||||
|
rate128 = 168
|
||||||
|
rate256 = 136
|
||||||
|
)
|
||||||
|
|
||||||
|
func bytepad(input []byte, w int) []byte {
|
||||||
|
// leftEncode always returns max 9 bytes
|
||||||
|
buf := make([]byte, 0, 9+len(input)+w)
|
||||||
|
buf = append(buf, leftEncode(uint64(w))...)
|
||||||
|
buf = append(buf, input...)
|
||||||
|
padlen := w - (len(buf) % w)
|
||||||
|
return append(buf, make([]byte, padlen)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func leftEncode(value uint64) []byte {
|
||||||
|
var b [9]byte
|
||||||
|
binary.BigEndian.PutUint64(b[1:], value)
|
||||||
|
// Trim all but last leading zero bytes
|
||||||
|
i := byte(1)
|
||||||
|
for i < 8 && b[i] == 0 {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
// Prepend number of encoded bytes
|
||||||
|
b[i-1] = 9 - i
|
||||||
|
return b[i-1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash {
|
||||||
|
c := cshakeState{state: &state{rate: rate, outputLen: outputLen, dsbyte: dsbyte}}
|
||||||
|
|
||||||
|
// leftEncode returns max 9 bytes
|
||||||
|
c.initBlock = make([]byte, 0, 9*2+len(N)+len(S))
|
||||||
|
c.initBlock = append(c.initBlock, leftEncode(uint64(len(N)*8))...)
|
||||||
|
c.initBlock = append(c.initBlock, N...)
|
||||||
|
c.initBlock = append(c.initBlock, leftEncode(uint64(len(S)*8))...)
|
||||||
|
c.initBlock = append(c.initBlock, S...)
|
||||||
|
c.Write(bytepad(c.initBlock, c.rate))
|
||||||
|
return &c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset resets the hash to initial state.
|
||||||
|
func (c *cshakeState) Reset() {
|
||||||
|
c.state.Reset()
|
||||||
|
c.Write(bytepad(c.initBlock, c.rate))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns copy of a cSHAKE context within its current state.
|
||||||
|
func (c *cshakeState) Clone() ShakeHash {
|
||||||
|
b := make([]byte, len(c.initBlock))
|
||||||
|
copy(b, c.initBlock)
|
||||||
|
return &cshakeState{state: c.clone(), initBlock: b}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns copy of SHAKE context within its current state.
|
||||||
|
func (c *state) Clone() ShakeHash {
|
||||||
|
return c.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
|
||||||
|
// Its generic security strength is 128 bits against all attacks if at
|
||||||
|
// least 32 bytes of its output are used.
|
||||||
|
func NewShake128() ShakeHash {
|
||||||
|
if h := newShake128Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
|
||||||
|
// Its generic security strength is 256 bits against all attacks if
|
||||||
|
// at least 64 bytes of its output are used.
|
||||||
|
func NewShake256() ShakeHash {
|
||||||
|
if h := newShake256Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,
|
||||||
|
// a customizable variant of SHAKE128.
|
||||||
|
// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
|
||||||
|
// desired. S is a customization byte string used for domain separation - two cSHAKE
|
||||||
|
// computations on same input with different S yield unrelated outputs.
|
||||||
|
// When N and S are both empty, this is equivalent to NewShake128.
|
||||||
|
func NewCShake128(N, S []byte) ShakeHash {
|
||||||
|
if len(N) == 0 && len(S) == 0 {
|
||||||
|
return NewShake128()
|
||||||
|
}
|
||||||
|
return newCShake(N, S, rate128, 32, dsbyteCShake)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash,
|
||||||
|
// a customizable variant of SHAKE256.
|
||||||
|
// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
|
||||||
|
// desired. S is a customization byte string used for domain separation - two cSHAKE
|
||||||
|
// computations on same input with different S yield unrelated outputs.
|
||||||
|
// When N and S are both empty, this is equivalent to NewShake256.
|
||||||
|
func NewCShake256(N, S []byte) ShakeHash {
|
||||||
|
if len(N) == 0 && len(S) == 0 {
|
||||||
|
return NewShake256()
|
||||||
|
}
|
||||||
|
return newCShake(N, S, rate256, 64, dsbyteCShake)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShakeSum128 writes an arbitrary-length digest of data into hash.
|
||||||
|
func ShakeSum128(hash, data []byte) {
|
||||||
|
h := NewShake128()
|
||||||
|
h.Write(data)
|
||||||
|
h.Read(hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShakeSum256 writes an arbitrary-length digest of data into hash.
|
||||||
|
func ShakeSum256(hash, data []byte) {
|
||||||
|
h := NewShake256()
|
||||||
|
h.Write(data)
|
||||||
|
h.Read(hash)
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gc || purego || !s390x
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func newShake128Asm() ShakeHash {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func newShake256Asm() ShakeHash {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build (!amd64 && !386 && !ppc64le) || purego
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// A storageBuf is an aligned array of maxRate bytes.
|
||||||
|
type storageBuf [maxRate]byte
|
||||||
|
|
||||||
|
func (b *storageBuf) asBytes() *[maxRate]byte {
|
||||||
|
return (*[maxRate]byte)(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
xorIn = xorInGeneric
|
||||||
|
copyOut = copyOutGeneric
|
||||||
|
xorInUnaligned = xorInGeneric
|
||||||
|
copyOutUnaligned = copyOutGeneric
|
||||||
|
)
|
||||||
|
|
||||||
|
const xorImplementationUnaligned = "generic"
|
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
import "encoding/binary"
|
||||||
|
|
||||||
|
// xorInGeneric xors the bytes in buf into the state; it
|
||||||
|
// makes no non-portable assumptions about memory layout
|
||||||
|
// or alignment.
|
||||||
|
func xorInGeneric(d *state, buf []byte) {
|
||||||
|
n := len(buf) / 8
|
||||||
|
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
a := binary.LittleEndian.Uint64(buf)
|
||||||
|
d.a[i] ^= a
|
||||||
|
buf = buf[8:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copyOutGeneric copies uint64s to a byte buffer.
|
||||||
|
func copyOutGeneric(d *state, b []byte) {
|
||||||
|
for i := 0; len(b) >= 8; i++ {
|
||||||
|
binary.LittleEndian.PutUint64(b, d.a[i])
|
||||||
|
b = b[8:]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build (amd64 || 386 || ppc64le) && !purego
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// A storageBuf is an aligned array of maxRate bytes.
|
||||||
|
type storageBuf [maxRate / 8]uint64
|
||||||
|
|
||||||
|
func (b *storageBuf) asBytes() *[maxRate]byte {
|
||||||
|
return (*[maxRate]byte)(unsafe.Pointer(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
|
||||||
|
// XOR buf.
|
||||||
|
func xorInUnaligned(d *state, buf []byte) {
|
||||||
|
n := len(buf)
|
||||||
|
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
|
||||||
|
if n >= 72 {
|
||||||
|
d.a[0] ^= bw[0]
|
||||||
|
d.a[1] ^= bw[1]
|
||||||
|
d.a[2] ^= bw[2]
|
||||||
|
d.a[3] ^= bw[3]
|
||||||
|
d.a[4] ^= bw[4]
|
||||||
|
d.a[5] ^= bw[5]
|
||||||
|
d.a[6] ^= bw[6]
|
||||||
|
d.a[7] ^= bw[7]
|
||||||
|
d.a[8] ^= bw[8]
|
||||||
|
}
|
||||||
|
if n >= 104 {
|
||||||
|
d.a[9] ^= bw[9]
|
||||||
|
d.a[10] ^= bw[10]
|
||||||
|
d.a[11] ^= bw[11]
|
||||||
|
d.a[12] ^= bw[12]
|
||||||
|
}
|
||||||
|
if n >= 136 {
|
||||||
|
d.a[13] ^= bw[13]
|
||||||
|
d.a[14] ^= bw[14]
|
||||||
|
d.a[15] ^= bw[15]
|
||||||
|
d.a[16] ^= bw[16]
|
||||||
|
}
|
||||||
|
if n >= 144 {
|
||||||
|
d.a[17] ^= bw[17]
|
||||||
|
}
|
||||||
|
if n >= 168 {
|
||||||
|
d.a[18] ^= bw[18]
|
||||||
|
d.a[19] ^= bw[19]
|
||||||
|
d.a[20] ^= bw[20]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyOutUnaligned(d *state, buf []byte) {
|
||||||
|
ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
|
||||||
|
copy(buf, ab[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
xorIn = xorInUnaligned
|
||||||
|
copyOut = copyOutUnaligned
|
||||||
|
)
|
||||||
|
|
||||||
|
const xorImplementationUnaligned = "unaligned"
|
|
@ -0,0 +1,27 @@
|
||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,22 @@
|
||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Go project.
|
||||||
|
|
||||||
|
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||||
|
patent license to make, have made, use, offer to sell, sell, import,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Go, where such license applies only to those patent
|
||||||
|
claims, both currently owned or controlled by Google and acquired in
|
||||||
|
the future, licensable by Google that are necessarily infringed by this
|
||||||
|
implementation of Go. This grant does not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of this
|
||||||
|
implementation. If you or your agent or exclusive licensee institute or
|
||||||
|
order or agree to the institution of patent litigation against any
|
||||||
|
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that this implementation of Go or any code incorporated within this
|
||||||
|
implementation of Go constitutes direct or contributory patent
|
||||||
|
infringement, or inducement of patent infringement, then any patent
|
||||||
|
rights granted to you under this License for this implementation of Go
|
||||||
|
shall terminate as of the date such litigation is filed.
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gc
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
|
||||||
|
//
|
||||||
|
|
||||||
|
TEXT ·syscall6(SB),NOSPLIT,$0-88
|
||||||
|
JMP syscall·syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
|
||||||
|
JMP syscall·rawSyscall6(SB)
|
|
@ -0,0 +1,66 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// byteOrder is a subset of encoding/binary.ByteOrder.
|
||||||
|
type byteOrder interface {
|
||||||
|
Uint32([]byte) uint32
|
||||||
|
Uint64([]byte) uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type littleEndian struct{}
|
||||||
|
type bigEndian struct{}
|
||||||
|
|
||||||
|
func (littleEndian) Uint32(b []byte) uint32 {
|
||||||
|
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) Uint64(b []byte) uint64 {
|
||||||
|
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
||||||
|
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) Uint32(b []byte) uint32 {
|
||||||
|
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) Uint64(b []byte) uint64 {
|
||||||
|
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
|
||||||
|
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
|
||||||
|
}
|
||||||
|
|
||||||
|
// hostByteOrder returns littleEndian on little-endian machines and
|
||||||
|
// bigEndian on big-endian machines.
|
||||||
|
func hostByteOrder() byteOrder {
|
||||||
|
switch runtime.GOARCH {
|
||||||
|
case "386", "amd64", "amd64p32",
|
||||||
|
"alpha",
|
||||||
|
"arm", "arm64",
|
||||||
|
"loong64",
|
||||||
|
"mipsle", "mips64le", "mips64p32le",
|
||||||
|
"nios2",
|
||||||
|
"ppc64le",
|
||||||
|
"riscv", "riscv64",
|
||||||
|
"sh":
|
||||||
|
return littleEndian{}
|
||||||
|
case "armbe", "arm64be",
|
||||||
|
"m68k",
|
||||||
|
"mips", "mips64", "mips64p32",
|
||||||
|
"ppc", "ppc64",
|
||||||
|
"s390", "s390x",
|
||||||
|
"shbe",
|
||||||
|
"sparc", "sparc64":
|
||||||
|
return bigEndian{}
|
||||||
|
}
|
||||||
|
panic("unknown architecture")
|
||||||
|
}
|
|
@ -0,0 +1,290 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package cpu implements processor feature detection for
|
||||||
|
// various CPU architectures.
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Initialized reports whether the CPU features were initialized.
|
||||||
|
//
|
||||||
|
// For some GOOS/GOARCH combinations initialization of the CPU features depends
|
||||||
|
// on reading an operating specific file, e.g. /proc/self/auxv on linux/arm
|
||||||
|
// Initialized will report false if reading the file fails.
|
||||||
|
var Initialized bool
|
||||||
|
|
||||||
|
// CacheLinePad is used to pad structs to avoid false sharing.
|
||||||
|
type CacheLinePad struct{ _ [cacheLineSize]byte }
|
||||||
|
|
||||||
|
// X86 contains the supported CPU features of the
|
||||||
|
// current X86/AMD64 platform. If the current platform
|
||||||
|
// is not X86/AMD64 then all feature flags are false.
|
||||||
|
//
|
||||||
|
// X86 is padded to avoid false sharing. Further the HasAVX
|
||||||
|
// and HasAVX2 are only set if the OS supports XMM and YMM
|
||||||
|
// registers in addition to the CPUID feature bit being set.
|
||||||
|
var X86 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasAES bool // AES hardware implementation (AES NI)
|
||||||
|
HasADX bool // Multi-precision add-carry instruction extensions
|
||||||
|
HasAVX bool // Advanced vector extension
|
||||||
|
HasAVX2 bool // Advanced vector extension 2
|
||||||
|
HasAVX512 bool // Advanced vector extension 512
|
||||||
|
HasAVX512F bool // Advanced vector extension 512 Foundation Instructions
|
||||||
|
HasAVX512CD bool // Advanced vector extension 512 Conflict Detection Instructions
|
||||||
|
HasAVX512ER bool // Advanced vector extension 512 Exponential and Reciprocal Instructions
|
||||||
|
HasAVX512PF bool // Advanced vector extension 512 Prefetch Instructions
|
||||||
|
HasAVX512VL bool // Advanced vector extension 512 Vector Length Extensions
|
||||||
|
HasAVX512BW bool // Advanced vector extension 512 Byte and Word Instructions
|
||||||
|
HasAVX512DQ bool // Advanced vector extension 512 Doubleword and Quadword Instructions
|
||||||
|
HasAVX512IFMA bool // Advanced vector extension 512 Integer Fused Multiply Add
|
||||||
|
HasAVX512VBMI bool // Advanced vector extension 512 Vector Byte Manipulation Instructions
|
||||||
|
HasAVX5124VNNIW bool // Advanced vector extension 512 Vector Neural Network Instructions Word variable precision
|
||||||
|
HasAVX5124FMAPS bool // Advanced vector extension 512 Fused Multiply Accumulation Packed Single precision
|
||||||
|
HasAVX512VPOPCNTDQ bool // Advanced vector extension 512 Double and quad word population count instructions
|
||||||
|
HasAVX512VPCLMULQDQ bool // Advanced vector extension 512 Vector carry-less multiply operations
|
||||||
|
HasAVX512VNNI bool // Advanced vector extension 512 Vector Neural Network Instructions
|
||||||
|
HasAVX512GFNI bool // Advanced vector extension 512 Galois field New Instructions
|
||||||
|
HasAVX512VAES bool // Advanced vector extension 512 Vector AES instructions
|
||||||
|
HasAVX512VBMI2 bool // Advanced vector extension 512 Vector Byte Manipulation Instructions 2
|
||||||
|
HasAVX512BITALG bool // Advanced vector extension 512 Bit Algorithms
|
||||||
|
HasAVX512BF16 bool // Advanced vector extension 512 BFloat16 Instructions
|
||||||
|
HasAMXTile bool // Advanced Matrix Extension Tile instructions
|
||||||
|
HasAMXInt8 bool // Advanced Matrix Extension Int8 instructions
|
||||||
|
HasAMXBF16 bool // Advanced Matrix Extension BFloat16 instructions
|
||||||
|
HasBMI1 bool // Bit manipulation instruction set 1
|
||||||
|
HasBMI2 bool // Bit manipulation instruction set 2
|
||||||
|
HasCX16 bool // Compare and exchange 16 Bytes
|
||||||
|
HasERMS bool // Enhanced REP for MOVSB and STOSB
|
||||||
|
HasFMA bool // Fused-multiply-add instructions
|
||||||
|
HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.
|
||||||
|
HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM
|
||||||
|
HasPOPCNT bool // Hamming weight instruction POPCNT.
|
||||||
|
HasRDRAND bool // RDRAND instruction (on-chip random number generator)
|
||||||
|
HasRDSEED bool // RDSEED instruction (on-chip random number generator)
|
||||||
|
HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64)
|
||||||
|
HasSSE3 bool // Streaming SIMD extension 3
|
||||||
|
HasSSSE3 bool // Supplemental streaming SIMD extension 3
|
||||||
|
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
|
||||||
|
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// ARM64 contains the supported CPU features of the
|
||||||
|
// current ARMv8(aarch64) platform. If the current platform
|
||||||
|
// is not arm64 then all feature flags are false.
|
||||||
|
var ARM64 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasFP bool // Floating-point instruction set (always available)
|
||||||
|
HasASIMD bool // Advanced SIMD (always available)
|
||||||
|
HasEVTSTRM bool // Event stream support
|
||||||
|
HasAES bool // AES hardware implementation
|
||||||
|
HasPMULL bool // Polynomial multiplication instruction set
|
||||||
|
HasSHA1 bool // SHA1 hardware implementation
|
||||||
|
HasSHA2 bool // SHA2 hardware implementation
|
||||||
|
HasCRC32 bool // CRC32 hardware implementation
|
||||||
|
HasATOMICS bool // Atomic memory operation instruction set
|
||||||
|
HasFPHP bool // Half precision floating-point instruction set
|
||||||
|
HasASIMDHP bool // Advanced SIMD half precision instruction set
|
||||||
|
HasCPUID bool // CPUID identification scheme registers
|
||||||
|
HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
|
||||||
|
HasJSCVT bool // Javascript conversion from floating-point to integer
|
||||||
|
HasFCMA bool // Floating-point multiplication and addition of complex numbers
|
||||||
|
HasLRCPC bool // Release Consistent processor consistent support
|
||||||
|
HasDCPOP bool // Persistent memory support
|
||||||
|
HasSHA3 bool // SHA3 hardware implementation
|
||||||
|
HasSM3 bool // SM3 hardware implementation
|
||||||
|
HasSM4 bool // SM4 hardware implementation
|
||||||
|
HasASIMDDP bool // Advanced SIMD double precision instruction set
|
||||||
|
HasSHA512 bool // SHA512 hardware implementation
|
||||||
|
HasSVE bool // Scalable Vector Extensions
|
||||||
|
HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// ARM contains the supported CPU features of the current ARM (32-bit) platform.
|
||||||
|
// All feature flags are false if:
|
||||||
|
// 1. the current platform is not arm, or
|
||||||
|
// 2. the current operating system is not Linux.
|
||||||
|
var ARM struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasSWP bool // SWP instruction support
|
||||||
|
HasHALF bool // Half-word load and store support
|
||||||
|
HasTHUMB bool // ARM Thumb instruction set
|
||||||
|
Has26BIT bool // Address space limited to 26-bits
|
||||||
|
HasFASTMUL bool // 32-bit operand, 64-bit result multiplication support
|
||||||
|
HasFPA bool // Floating point arithmetic support
|
||||||
|
HasVFP bool // Vector floating point support
|
||||||
|
HasEDSP bool // DSP Extensions support
|
||||||
|
HasJAVA bool // Java instruction set
|
||||||
|
HasIWMMXT bool // Intel Wireless MMX technology support
|
||||||
|
HasCRUNCH bool // MaverickCrunch context switching and handling
|
||||||
|
HasTHUMBEE bool // Thumb EE instruction set
|
||||||
|
HasNEON bool // NEON instruction set
|
||||||
|
HasVFPv3 bool // Vector floating point version 3 support
|
||||||
|
HasVFPv3D16 bool // Vector floating point version 3 D8-D15
|
||||||
|
HasTLS bool // Thread local storage support
|
||||||
|
HasVFPv4 bool // Vector floating point version 4 support
|
||||||
|
HasIDIVA bool // Integer divide instruction support in ARM mode
|
||||||
|
HasIDIVT bool // Integer divide instruction support in Thumb mode
|
||||||
|
HasVFPD32 bool // Vector floating point version 3 D15-D31
|
||||||
|
HasLPAE bool // Large Physical Address Extensions
|
||||||
|
HasEVTSTRM bool // Event stream support
|
||||||
|
HasAES bool // AES hardware implementation
|
||||||
|
HasPMULL bool // Polynomial multiplication instruction set
|
||||||
|
HasSHA1 bool // SHA1 hardware implementation
|
||||||
|
HasSHA2 bool // SHA2 hardware implementation
|
||||||
|
HasCRC32 bool // CRC32 hardware implementation
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// MIPS64X contains the supported CPU features of the current mips64/mips64le
|
||||||
|
// platforms. If the current platform is not mips64/mips64le or the current
|
||||||
|
// operating system is not Linux then all feature flags are false.
|
||||||
|
var MIPS64X struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasMSA bool // MIPS SIMD architecture
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms.
|
||||||
|
// If the current platform is not ppc64/ppc64le then all feature flags are false.
|
||||||
|
//
|
||||||
|
// For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00,
|
||||||
|
// since there are no optional categories. There are some exceptions that also
|
||||||
|
// require kernel support to work (DARN, SCV), so there are feature bits for
|
||||||
|
// those as well. The struct is padded to avoid false sharing.
|
||||||
|
var PPC64 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasDARN bool // Hardware random number generator (requires kernel enablement)
|
||||||
|
HasSCV bool // Syscall vectored (requires kernel enablement)
|
||||||
|
IsPOWER8 bool // ISA v2.07 (POWER8)
|
||||||
|
IsPOWER9 bool // ISA v3.00 (POWER9), implies IsPOWER8
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// S390X contains the supported CPU features of the current IBM Z
|
||||||
|
// (s390x) platform. If the current platform is not IBM Z then all
|
||||||
|
// feature flags are false.
|
||||||
|
//
|
||||||
|
// S390X is padded to avoid false sharing. Further HasVX is only set
|
||||||
|
// if the OS supports vector registers in addition to the STFLE
|
||||||
|
// feature bit being set.
|
||||||
|
var S390X struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasZARCH bool // z/Architecture mode is active [mandatory]
|
||||||
|
HasSTFLE bool // store facility list extended
|
||||||
|
HasLDISP bool // long (20-bit) displacements
|
||||||
|
HasEIMM bool // 32-bit immediates
|
||||||
|
HasDFP bool // decimal floating point
|
||||||
|
HasETF3EH bool // ETF-3 enhanced
|
||||||
|
HasMSA bool // message security assist (CPACF)
|
||||||
|
HasAES bool // KM-AES{128,192,256} functions
|
||||||
|
HasAESCBC bool // KMC-AES{128,192,256} functions
|
||||||
|
HasAESCTR bool // KMCTR-AES{128,192,256} functions
|
||||||
|
HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
|
||||||
|
HasGHASH bool // KIMD-GHASH function
|
||||||
|
HasSHA1 bool // K{I,L}MD-SHA-1 functions
|
||||||
|
HasSHA256 bool // K{I,L}MD-SHA-256 functions
|
||||||
|
HasSHA512 bool // K{I,L}MD-SHA-512 functions
|
||||||
|
HasSHA3 bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions
|
||||||
|
HasVX bool // vector facility
|
||||||
|
HasVXE bool // vector-enhancements facility 1
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
archInit()
|
||||||
|
initOptions()
|
||||||
|
processOptions()
|
||||||
|
}
|
||||||
|
|
||||||
|
// options contains the cpu debug options that can be used in GODEBUG.
|
||||||
|
// Options are arch dependent and are added by the arch specific initOptions functions.
|
||||||
|
// Features that are mandatory for the specific GOARCH should have the Required field set
|
||||||
|
// (e.g. SSE2 on amd64).
|
||||||
|
var options []option
|
||||||
|
|
||||||
|
// Option names should be lower case. e.g. avx instead of AVX.
|
||||||
|
type option struct {
|
||||||
|
Name string
|
||||||
|
Feature *bool
|
||||||
|
Specified bool // whether feature value was specified in GODEBUG
|
||||||
|
Enable bool // whether feature should be enabled
|
||||||
|
Required bool // whether feature is mandatory and can not be disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
func processOptions() {
|
||||||
|
env := os.Getenv("GODEBUG")
|
||||||
|
field:
|
||||||
|
for env != "" {
|
||||||
|
field := ""
|
||||||
|
i := strings.IndexByte(env, ',')
|
||||||
|
if i < 0 {
|
||||||
|
field, env = env, ""
|
||||||
|
} else {
|
||||||
|
field, env = env[:i], env[i+1:]
|
||||||
|
}
|
||||||
|
if len(field) < 4 || field[:4] != "cpu." {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i = strings.IndexByte(field, '=')
|
||||||
|
if i < 0 {
|
||||||
|
print("GODEBUG sys/cpu: no value specified for \"", field, "\"\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
key, value := field[4:i], field[i+1:] // e.g. "SSE2", "on"
|
||||||
|
|
||||||
|
var enable bool
|
||||||
|
switch value {
|
||||||
|
case "on":
|
||||||
|
enable = true
|
||||||
|
case "off":
|
||||||
|
enable = false
|
||||||
|
default:
|
||||||
|
print("GODEBUG sys/cpu: value \"", value, "\" not supported for cpu option \"", key, "\"\n")
|
||||||
|
continue field
|
||||||
|
}
|
||||||
|
|
||||||
|
if key == "all" {
|
||||||
|
for i := range options {
|
||||||
|
options[i].Specified = true
|
||||||
|
options[i].Enable = enable || options[i].Required
|
||||||
|
}
|
||||||
|
continue field
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range options {
|
||||||
|
if options[i].Name == key {
|
||||||
|
options[i].Specified = true
|
||||||
|
options[i].Enable = enable
|
||||||
|
continue field
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("GODEBUG sys/cpu: unknown cpu feature \"", key, "\"\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range options {
|
||||||
|
if !o.Specified {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.Enable && !*o.Feature {
|
||||||
|
print("GODEBUG sys/cpu: can not enable \"", o.Name, "\", missing CPU support\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !o.Enable && o.Required {
|
||||||
|
print("GODEBUG sys/cpu: can not disable \"", o.Name, "\", required CPU feature\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
*o.Feature = o.Enable
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build aix
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const (
|
||||||
|
// getsystemcfg constants
|
||||||
|
_SC_IMPL = 2
|
||||||
|
_IMPL_POWER8 = 0x10000
|
||||||
|
_IMPL_POWER9 = 0x20000
|
||||||
|
)
|
||||||
|
|
||||||
|
func archInit() {
|
||||||
|
impl := getsystemcfg(_SC_IMPL)
|
||||||
|
if impl&_IMPL_POWER8 != 0 {
|
||||||
|
PPC64.IsPOWER8 = true
|
||||||
|
}
|
||||||
|
if impl&_IMPL_POWER9 != 0 {
|
||||||
|
PPC64.IsPOWER8 = true
|
||||||
|
PPC64.IsPOWER9 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Initialized = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func getsystemcfg(label int) (n uint64) {
|
||||||
|
r0, _ := callgetsystemcfg(label)
|
||||||
|
n = uint64(r0)
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 32
|
||||||
|
|
||||||
|
// HWCAP/HWCAP2 bits.
|
||||||
|
// These are specific to Linux.
|
||||||
|
const (
|
||||||
|
hwcap_SWP = 1 << 0
|
||||||
|
hwcap_HALF = 1 << 1
|
||||||
|
hwcap_THUMB = 1 << 2
|
||||||
|
hwcap_26BIT = 1 << 3
|
||||||
|
hwcap_FAST_MULT = 1 << 4
|
||||||
|
hwcap_FPA = 1 << 5
|
||||||
|
hwcap_VFP = 1 << 6
|
||||||
|
hwcap_EDSP = 1 << 7
|
||||||
|
hwcap_JAVA = 1 << 8
|
||||||
|
hwcap_IWMMXT = 1 << 9
|
||||||
|
hwcap_CRUNCH = 1 << 10
|
||||||
|
hwcap_THUMBEE = 1 << 11
|
||||||
|
hwcap_NEON = 1 << 12
|
||||||
|
hwcap_VFPv3 = 1 << 13
|
||||||
|
hwcap_VFPv3D16 = 1 << 14
|
||||||
|
hwcap_TLS = 1 << 15
|
||||||
|
hwcap_VFPv4 = 1 << 16
|
||||||
|
hwcap_IDIVA = 1 << 17
|
||||||
|
hwcap_IDIVT = 1 << 18
|
||||||
|
hwcap_VFPD32 = 1 << 19
|
||||||
|
hwcap_LPAE = 1 << 20
|
||||||
|
hwcap_EVTSTRM = 1 << 21
|
||||||
|
|
||||||
|
hwcap2_AES = 1 << 0
|
||||||
|
hwcap2_PMULL = 1 << 1
|
||||||
|
hwcap2_SHA1 = 1 << 2
|
||||||
|
hwcap2_SHA2 = 1 << 3
|
||||||
|
hwcap2_CRC32 = 1 << 4
|
||||||
|
)
|
||||||
|
|
||||||
|
func initOptions() {
|
||||||
|
options = []option{
|
||||||
|
{Name: "pmull", Feature: &ARM.HasPMULL},
|
||||||
|
{Name: "sha1", Feature: &ARM.HasSHA1},
|
||||||
|
{Name: "sha2", Feature: &ARM.HasSHA2},
|
||||||
|
{Name: "swp", Feature: &ARM.HasSWP},
|
||||||
|
{Name: "thumb", Feature: &ARM.HasTHUMB},
|
||||||
|
{Name: "thumbee", Feature: &ARM.HasTHUMBEE},
|
||||||
|
{Name: "tls", Feature: &ARM.HasTLS},
|
||||||
|
{Name: "vfp", Feature: &ARM.HasVFP},
|
||||||
|
{Name: "vfpd32", Feature: &ARM.HasVFPD32},
|
||||||
|
{Name: "vfpv3", Feature: &ARM.HasVFPv3},
|
||||||
|
{Name: "vfpv3d16", Feature: &ARM.HasVFPv3D16},
|
||||||
|
{Name: "vfpv4", Feature: &ARM.HasVFPv4},
|
||||||
|
{Name: "half", Feature: &ARM.HasHALF},
|
||||||
|
{Name: "26bit", Feature: &ARM.Has26BIT},
|
||||||
|
{Name: "fastmul", Feature: &ARM.HasFASTMUL},
|
||||||
|
{Name: "fpa", Feature: &ARM.HasFPA},
|
||||||
|
{Name: "edsp", Feature: &ARM.HasEDSP},
|
||||||
|
{Name: "java", Feature: &ARM.HasJAVA},
|
||||||
|
{Name: "iwmmxt", Feature: &ARM.HasIWMMXT},
|
||||||
|
{Name: "crunch", Feature: &ARM.HasCRUNCH},
|
||||||
|
{Name: "neon", Feature: &ARM.HasNEON},
|
||||||
|
{Name: "idivt", Feature: &ARM.HasIDIVT},
|
||||||
|
{Name: "idiva", Feature: &ARM.HasIDIVA},
|
||||||
|
{Name: "lpae", Feature: &ARM.HasLPAE},
|
||||||
|
{Name: "evtstrm", Feature: &ARM.HasEVTSTRM},
|
||||||
|
{Name: "aes", Feature: &ARM.HasAES},
|
||||||
|
{Name: "crc32", Feature: &ARM.HasCRC32},
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,172 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
import "runtime"
|
||||||
|
|
||||||
|
// cacheLineSize is used to prevent false sharing of cache lines.
|
||||||
|
// We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size.
|
||||||
|
// It doesn't cost much and is much more future-proof.
|
||||||
|
const cacheLineSize = 128
|
||||||
|
|
||||||
|
func initOptions() {
|
||||||
|
options = []option{
|
||||||
|
{Name: "fp", Feature: &ARM64.HasFP},
|
||||||
|
{Name: "asimd", Feature: &ARM64.HasASIMD},
|
||||||
|
{Name: "evstrm", Feature: &ARM64.HasEVTSTRM},
|
||||||
|
{Name: "aes", Feature: &ARM64.HasAES},
|
||||||
|
{Name: "fphp", Feature: &ARM64.HasFPHP},
|
||||||
|
{Name: "jscvt", Feature: &ARM64.HasJSCVT},
|
||||||
|
{Name: "lrcpc", Feature: &ARM64.HasLRCPC},
|
||||||
|
{Name: "pmull", Feature: &ARM64.HasPMULL},
|
||||||
|
{Name: "sha1", Feature: &ARM64.HasSHA1},
|
||||||
|
{Name: "sha2", Feature: &ARM64.HasSHA2},
|
||||||
|
{Name: "sha3", Feature: &ARM64.HasSHA3},
|
||||||
|
{Name: "sha512", Feature: &ARM64.HasSHA512},
|
||||||
|
{Name: "sm3", Feature: &ARM64.HasSM3},
|
||||||
|
{Name: "sm4", Feature: &ARM64.HasSM4},
|
||||||
|
{Name: "sve", Feature: &ARM64.HasSVE},
|
||||||
|
{Name: "crc32", Feature: &ARM64.HasCRC32},
|
||||||
|
{Name: "atomics", Feature: &ARM64.HasATOMICS},
|
||||||
|
{Name: "asimdhp", Feature: &ARM64.HasASIMDHP},
|
||||||
|
{Name: "cpuid", Feature: &ARM64.HasCPUID},
|
||||||
|
{Name: "asimrdm", Feature: &ARM64.HasASIMDRDM},
|
||||||
|
{Name: "fcma", Feature: &ARM64.HasFCMA},
|
||||||
|
{Name: "dcpop", Feature: &ARM64.HasDCPOP},
|
||||||
|
{Name: "asimddp", Feature: &ARM64.HasASIMDDP},
|
||||||
|
{Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func archInit() {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "freebsd":
|
||||||
|
readARM64Registers()
|
||||||
|
case "linux", "netbsd", "openbsd":
|
||||||
|
doinit()
|
||||||
|
default:
|
||||||
|
// Many platforms don't seem to allow reading these registers.
|
||||||
|
setMinimalFeatures()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setMinimalFeatures fakes the minimal ARM64 features expected by
|
||||||
|
// TestARM64minimalFeatures.
|
||||||
|
func setMinimalFeatures() {
|
||||||
|
ARM64.HasASIMD = true
|
||||||
|
ARM64.HasFP = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func readARM64Registers() {
|
||||||
|
Initialized = true
|
||||||
|
|
||||||
|
parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0())
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) {
|
||||||
|
// ID_AA64ISAR0_EL1
|
||||||
|
switch extractBits(isar0, 4, 7) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasAES = true
|
||||||
|
case 2:
|
||||||
|
ARM64.HasAES = true
|
||||||
|
ARM64.HasPMULL = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 8, 11) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSHA1 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 12, 15) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSHA2 = true
|
||||||
|
case 2:
|
||||||
|
ARM64.HasSHA2 = true
|
||||||
|
ARM64.HasSHA512 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 16, 19) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasCRC32 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 20, 23) {
|
||||||
|
case 2:
|
||||||
|
ARM64.HasATOMICS = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 28, 31) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasASIMDRDM = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 32, 35) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSHA3 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 36, 39) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSM3 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 40, 43) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSM4 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 44, 47) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasASIMDDP = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID_AA64ISAR1_EL1
|
||||||
|
switch extractBits(isar1, 0, 3) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasDCPOP = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar1, 12, 15) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasJSCVT = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar1, 16, 19) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasFCMA = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar1, 20, 23) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasLRCPC = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID_AA64PFR0_EL1
|
||||||
|
switch extractBits(pfr0, 16, 19) {
|
||||||
|
case 0:
|
||||||
|
ARM64.HasFP = true
|
||||||
|
case 1:
|
||||||
|
ARM64.HasFP = true
|
||||||
|
ARM64.HasFPHP = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(pfr0, 20, 23) {
|
||||||
|
case 0:
|
||||||
|
ARM64.HasASIMD = true
|
||||||
|
case 1:
|
||||||
|
ARM64.HasASIMD = true
|
||||||
|
ARM64.HasASIMDHP = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(pfr0, 32, 35) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSVE = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractBits(data uint64, start, end uint) uint {
|
||||||
|
return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gc
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// func getisar0() uint64
|
||||||
|
TEXT ·getisar0(SB),NOSPLIT,$0-8
|
||||||
|
// get Instruction Set Attributes 0 into x0
|
||||||
|
// mrs x0, ID_AA64ISAR0_EL1 = d5380600
|
||||||
|
WORD $0xd5380600
|
||||||
|
MOVD R0, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func getisar1() uint64
|
||||||
|
TEXT ·getisar1(SB),NOSPLIT,$0-8
|
||||||
|
// get Instruction Set Attributes 1 into x0
|
||||||
|
// mrs x0, ID_AA64ISAR1_EL1 = d5380620
|
||||||
|
WORD $0xd5380620
|
||||||
|
MOVD R0, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func getpfr0() uint64
|
||||||
|
TEXT ·getpfr0(SB),NOSPLIT,$0-8
|
||||||
|
// get Processor Feature Register 0 into x0
|
||||||
|
// mrs x0, ID_AA64PFR0_EL1 = d5380400
|
||||||
|
WORD $0xd5380400
|
||||||
|
MOVD R0, ret+0(FP)
|
||||||
|
RET
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue