code: func VerifyDetachedReader(versionValidator VersionValidator, message io.Reader, signature []byte, keyring SigKeyring) (skey SigningPublicKey, err error) {
  	inputBuffer := bytes.NewBuffer(signature)
  
  	// Use a verifyStream to parse the header.
  	s, err := newVerifyStream(versionValidator, inputBuffer, MessageTypeDetachedSignature)
  	if err != nil {
  		return nil, err
  	}
  
  	// Reach inside the verifyStream to parse the signature bytes.
  	var naclSignature []byte
  	_, err = s.mps.Read(&naclSignature)
  	if err != nil {
  		return nil, err
  	}
  
  	// Get the public key.
  	skey = keyring.LookupSigningPublicKey(s.header.SenderPublic)
  	if skey == nil {
  		return nil, ErrNoSenderKey
  	}
  
  	// Compute the signed text hash, without requiring us to copy the whole
  	// signed text into memory at once.
  	hasher := sha512.New()
  	hasher.Write(s.headerHash[:])
  	if _, err := io.Copy(hasher, message); err != nil {
  		return nil, err
  	}
  
  	if err := skey.Verify(detachedSignatureInputFromHash(hasher.Sum(nil)), naclSignature); err != nil {
  		return nil, err
  	}
  
  	return skey, nil
  }
docs: // VerifyDetachedReader verifies that signature is a valid signature for
  // entire message read from message Reader, and that the public key for
  // the signer is in keyring. It returns the signer's public key.