github.com/ethersphere/bee/v2@v2.2.0/pkg/accesscontrol/session.go (about) 1 // Copyright 2024 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package accesscontrol 6 7 import ( 8 "crypto/ecdsa" 9 "errors" 10 "fmt" 11 12 "github.com/ethersphere/bee/v2/pkg/crypto" 13 ) 14 15 var ( 16 // ErrInvalidPublicKey is an error that is returned when a public key is nil. 17 ErrInvalidPublicKey = errors.New("invalid public key") 18 // ErrSecretKeyInfinity is an error that is returned when the shared secret is a point at infinity. 19 ErrSecretKeyInfinity = errors.New("shared secret is point at infinity") 20 ) 21 22 // Session represents an interface for a Diffie-Hellmann key derivation 23 type Session interface { 24 // Key returns a derived key for each nonce. 25 Key(publicKey *ecdsa.PublicKey, nonces [][]byte) ([][]byte, error) 26 } 27 28 var _ Session = (*SessionStruct)(nil) 29 30 // SessionStruct represents a session with an access control key. 31 type SessionStruct struct { 32 key *ecdsa.PrivateKey 33 } 34 35 // Key returns a derived key for each nonce. 36 func (s *SessionStruct) Key(publicKey *ecdsa.PublicKey, nonces [][]byte) ([][]byte, error) { 37 if publicKey == nil { 38 return nil, ErrInvalidPublicKey 39 } 40 x, y := publicKey.Curve.ScalarMult(publicKey.X, publicKey.Y, s.key.D.Bytes()) 41 if x == nil || y == nil { 42 return nil, ErrSecretKeyInfinity 43 } 44 45 if len(nonces) == 0 { 46 return [][]byte{(*x).Bytes()}, nil 47 } 48 49 keys := make([][]byte, 0, len(nonces)) 50 for _, nonce := range nonces { 51 key, err := crypto.LegacyKeccak256(append(x.Bytes(), nonce...)) 52 if err != nil { 53 return nil, fmt.Errorf("failed to get Keccak256 hash: %w", err) 54 } 55 keys = append(keys, key) 56 } 57 58 return keys, nil 59 } 60 61 // NewDefaultSession creates a new session from a private key. 62 func NewDefaultSession(key *ecdsa.PrivateKey) *SessionStruct { 63 return &SessionStruct{ 64 key: key, 65 } 66 }