1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- package noiseutil
- import (
- "crypto/ecdh"
- "crypto/rand"
- "fmt"
- "io"
- "github.com/flynn/noise"
- )
- // DHP256 is the NIST P-256 ECDH function
- var DHP256 noise.DHFunc = newNISTCurve("P256", ecdh.P256(), 32)
- type nistCurve struct {
- name string
- curve ecdh.Curve
- dhLen int
- pubLen int
- }
- func newNISTCurve(name string, curve ecdh.Curve, byteLen int) nistCurve {
- return nistCurve{
- name: name,
- curve: curve,
- dhLen: byteLen,
- // Standard uncompressed format, type (1 byte) plus both coordinates
- pubLen: 1 + 2*byteLen,
- }
- }
- func (c nistCurve) GenerateKeypair(rng io.Reader) (noise.DHKey, error) {
- if rng == nil {
- rng = rand.Reader
- }
- privkey, err := c.curve.GenerateKey(rng)
- if err != nil {
- return noise.DHKey{}, err
- }
- pubkey := privkey.PublicKey()
- return noise.DHKey{Private: privkey.Bytes(), Public: pubkey.Bytes()}, nil
- }
- func (c nistCurve) DH(privkey, pubkey []byte) ([]byte, error) {
- ecdhPubKey, err := c.curve.NewPublicKey(pubkey)
- if err != nil {
- return nil, fmt.Errorf("unable to unmarshal pubkey: %w", err)
- }
- ecdhPrivKey, err := c.curve.NewPrivateKey(privkey)
- if err != nil {
- return nil, fmt.Errorf("unable to unmarshal pubkey: %w", err)
- }
- return ecdhPrivKey.ECDH(ecdhPubKey)
- }
- func (c nistCurve) DHLen() int {
- // NOTE: Noise Protocol specifies "DHLen" to represent two things:
- // - The size of the public key
- // - The return size of the DH() function
- // But for standard NIST ECDH, the sizes of these are different.
- // Luckily, the flynn/noise library actually only uses this DHLen()
- // value to represent the public key size, so that is what we are
- // returning here. The length of the DH() return bytes are unaffected by
- // this value here.
- return c.pubLen
- }
- func (c nistCurve) DHName() string { return c.name }
|