File: x25519.go

package info (click to toggle)
golang-github-smallstep-crypto 0.63.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,800 kB
  • sloc: sh: 66; makefile: 50
file content (66 lines) | stat: -rw-r--r-- 2,023 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
61
62
63
64
65
66
package jose

import (
	"crypto"
	"crypto/rand"
	"encoding/base64"
	"fmt"

	"github.com/pkg/errors"
	"go.step.sm/crypto/x25519"
)

const x25519ThumbprintTemplate = `{"crv":"X25519","kty":"OKP","x":%q}`

func x25519Thumbprint(key x25519.PublicKey, hash crypto.Hash) ([]byte, error) {
	if len(key) != 32 {
		return nil, errors.New("invalid elliptic key")
	}
	h := hash.New()
	fmt.Fprintf(h, x25519ThumbprintTemplate, base64.RawURLEncoding.EncodeToString(key))
	return h.Sum(nil), nil
}

// X25519Signer implements the jose.OpaqueSigner using an X25519 key and XEdDSA
// as the signing algorithm.
type X25519Signer x25519.PrivateKey

// Public returns the public key of the current signing key.
func (s X25519Signer) Public() *JSONWebKey {
	return &JSONWebKey{
		Key: x25519.PrivateKey(s).Public(),
	}
}

// Algs returns a list of supported signing algorithms, in this case only
// XEdDSA.
func (s X25519Signer) Algs() []SignatureAlgorithm {
	return []SignatureAlgorithm{
		XEdDSA,
	}
}

// SignPayload signs a payload with the current signing key using the given
// algorithm, it will fail if it's not XEdDSA.
func (s X25519Signer) SignPayload(payload []byte, alg SignatureAlgorithm) ([]byte, error) {
	if alg != XEdDSA {
		return nil, errors.Errorf("x25519 key does not support the signature algorithm %s", alg)
	}
	return x25519.PrivateKey(s).Sign(rand.Reader, payload, crypto.Hash(0))
}

// X25519Verifier implements the jose.OpaqueVerifier interface using an X25519
// key and XEdDSA as a signing algorithm.
type X25519Verifier x25519.PublicKey

// VerifyPayload verifies the given signature using the X25519 public key, it
// will fail if the signature algorithm is not XEdDSA.
func (v X25519Verifier) VerifyPayload(payload, signature []byte, alg SignatureAlgorithm) error {
	if alg != XEdDSA {
		return errors.Errorf("x25519 key does not support the signature algorithm %s", alg)
	}
	if !x25519.Verify(x25519.PublicKey(v), payload, signature) {
		return errors.New("failed to verify XEdDSA signature")
	}
	return nil
}