I've always understood the purpose of signing an assembly to be a runtime check to ensure that upgrades to the code come from a trusted source. Effectively they are trying to avoid this kind of scenario:
I purchase a encryption library from Company A, shortly afterwards Company B gets hold of my email details and sends me a free upgrade to the assembly pretending to be a major security bug fix from Company A when it really injects a hidden method into my code that sends all the data I was trying to encrypt off to company B's servers. Assuming that I'm an idiot and blindly add this new dll into my application's bin directory the fact that this wasn't signed with the same private key as the old version will be picked up at runtime causing an exception and protecting my data.
So, I see no reason that you would publish the public key outside of the assembly since it isn't supposed to guarantee that the original file comes from a specific vendor, only that all subsequent versions come from the same place as the first.
Wikipedia says much the same thing (only in significantly fewer words).
Edited to add further information in an attempt to make this clearer...
I think the thing that needs to be clarified first is that the pairs of public and private keys are unique. That means that knowing the public key is not enough information to rebuild the assembly in a way that it will pass the same hash checks.
So User Z who is using an encryption library from Company A which is in his applications bin folder. To do this he is referencing the DLL as follows:
Encryption, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bcd6707151635d07"
The purpose of the public key is to provide us with three benefits which I'll handle one at a time.
Firstly, it provides a unique name for the assembly - this gives us no extra security but does stop C style dll Hell where two different companies could release two different libraries called Encyption version 1.0.0.0 and you wouldn't be able to store them in the same directory since there is no way to differentiate them.
Secondly, it prevents the scenario that I outlined in my original post. It is impossible for Company B to create another version of the Encryption library which is also version 1.0.0.0 and has the same public key (so that the whole name would match and you'd call their code instead of Company A's). They can't do this because if their public key matched then the private key must also match (since each pair is unique). The only way they can get the private key to match is by compromising Company A's security.
Finally it ensures the integrity of the file (either changed through corruption or malicious code injection). The dll is hashed at runtime (when it is private and in the bin folder of the application) or install time (when you put it in the GAC) using the public key and that hash is compared to the hash that was encrpyted by the private key and stored in the assembly. This page has some diagrams and more details. Once again the only way to fake this hash is to know the private key.
So, to cover the specific scenario that I described above, pretend that I am Company B trying to supply User Z with a malicious version of the encryption dll. My first attempt is to simply make my own dll with the name Encryption and Version 1.0.0.0 and sign it with my own key pair. Unfortunately I can't change the reference code in User Z's application so it fails the full name check and doesn't get loaded. "Okay," says I while twirling my moustache, "I'll simply change the public key of my assembly to match that of Company A's". Once I've done this the name check passes, but the hash check will fail because User Z's app won't be able to decrypt the hash stored in the assembly (which was encrypted with Company B's private key) with the public key (Company A's) that has been supplied. Therefore the only way for Company B to create a library that pretends to be Company A's is to know Company A's private key. None of these security checks are reliant on Company A publishing the public key anywhere else but in the original release of the assembly.
Note also that all of these features don't ensure (and don't claim to ensure) that the original assembly came from Company A, that is handled by other systems such as Verisign or Microsoft's Authenticode service, they only ensure that once you have referenced the assembly only Company A can make changes to that code.