code: func (s *Service) SignRequestWithKey(r *http.Request, secretKey []byte) error {
  	// extract request body bytes
  	bodyBytes, err := readBody(r)
  	if err != nil {
  		return err
  	}
  
  	// extract any headers if requested
  	headerValues, err := extractHeaderValues(r, s.config.HeadersToSign)
  	if err != nil {
  		return err
  	}
  
  	// get 128-bit random number from /dev/urandom and base16 encode it
  	nonce, err := s.randomProvider.HexDigest(16)
  	if err != nil {
  		return fmt.Errorf("unable to get random : %v", err)
  	}
  
  	// get current timestamp
  	timestamp := strconv.FormatInt(s.timeProvider.UtcNow().Unix(), 10)
  
  	// compute the hmac and base16 encode it
  	computedMAC := computeMAC(secretKey, s.config.SignVerbAndURI, r.Method, r.URL.RequestURI(),
  		timestamp, nonce, bodyBytes, headerValues)
  	signature := hex.EncodeToString(computedMAC)
  
  	// set headers
  	r.Header.Set(s.config.NonceHeaderName, nonce)
  	r.Header.Set(s.config.TimestampHeaderName, timestamp)
  	r.Header.Set(s.config.SignatureHeaderName, signature)
  	r.Header.Set(s.config.SignatureVersionHeaderName, "2")
  
  	// set the body bytes we read in to nil to hint to the gc to pick it up
  	bodyBytes = nil
  
  	return nil
  }
docs: // Signs a given HTTP request with signature, nonce, and timestamp. Signs the
  // message with the passed in key not the one initialized with.