|
@@ -0,0 +1,95 @@
|
|
|
+package main
|
|
|
+
|
|
|
+import (
|
|
|
+ "crypto"
|
|
|
+ "crypto/ed25519"
|
|
|
+ "crypto/rand"
|
|
|
+ "crypto/sha512"
|
|
|
+ "fmt"
|
|
|
+ "github.com/urfave/cli/v2"
|
|
|
+ "io"
|
|
|
+ "os"
|
|
|
+)
|
|
|
+
|
|
|
+func SignFileS512(c *cli.Context) error {
|
|
|
+ _, prvBin, err := LoadKey(c)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if len(prvBin) != ed25519.PrivateKeySize {
|
|
|
+ return fmt.Errorf("invalid private key size: should be %d, got %d", ed25519.PrivateKeySize, len(prvBin))
|
|
|
+ }
|
|
|
+ prvKey := ed25519.PrivateKey(prvBin)
|
|
|
+ filename := c.String("file")
|
|
|
+ output := c.String("out")
|
|
|
+ if filename == "" {
|
|
|
+ return fmt.Errorf("flag 'file' should not be empty")
|
|
|
+ }
|
|
|
+ if output == "" {
|
|
|
+ output = filename + ".ng-edst-s512-sig"
|
|
|
+ }
|
|
|
+ f, err := os.Open(filename)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to open file '%s': %w", filename, err)
|
|
|
+ }
|
|
|
+ hasher := sha512.New()
|
|
|
+ _, err = io.Copy(hasher, f)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to hash file '%s': %w", filename, err)
|
|
|
+ }
|
|
|
+ fsum := hasher.Sum(nil)
|
|
|
+ sig, err := prvKey.Sign(rand.Reader, fsum, &ed25519.Options{
|
|
|
+ Hash: crypto.Hash(0),
|
|
|
+ Context: "",
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to sign with ed25519: %w", err)
|
|
|
+ }
|
|
|
+ err = os.WriteFile(output, sig, 0660)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to write file: %w", err)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+func VerifyFileS512(c *cli.Context) error {
|
|
|
+ pubBin, _, err := LoadKey(c)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if len(pubBin) != ed25519.PublicKeySize {
|
|
|
+ return fmt.Errorf("invalid public key size: should be %d but got %d", ed25519.PublicKeySize, len(pubBin))
|
|
|
+ }
|
|
|
+ pubKey := ed25519.PublicKey(pubBin)
|
|
|
+ filename := c.String("file")
|
|
|
+ sigfile := c.String("sig")
|
|
|
+ if filename == "" {
|
|
|
+ return fmt.Errorf("flag 'file' should not be empty")
|
|
|
+ }
|
|
|
+ if sigfile == "" {
|
|
|
+ sigfile = filename + ".ng-edst-s512-sig"
|
|
|
+ }
|
|
|
+ f, err := os.Open(filename)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to open file '%s': %w", filename, err)
|
|
|
+ }
|
|
|
+ hasher := sha512.New()
|
|
|
+ _, err = io.Copy(hasher, f)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to hash file '%s': %w", filename, err)
|
|
|
+ }
|
|
|
+ fsum := hasher.Sum(nil)
|
|
|
+ sbin, err := os.ReadFile(sigfile)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to read sig file '%s': %w", sigfile, err)
|
|
|
+ }
|
|
|
+ err = ed25519.VerifyWithOptions(pubKey, fsum, sbin, &ed25519.Options{
|
|
|
+ Hash: crypto.Hash(0),
|
|
|
+ Context: "",
|
|
|
+ })
|
|
|
+ if err == nil {
|
|
|
+ fmt.Println("Verify OK.")
|
|
|
+ } else {
|
|
|
+ fmt.Println("verify FAIL: ", err)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|