Zero-knowledge proofs are proofs that are both convincing and yet yield nothing beyond the validity of the assertion being proved. Their direct applications in cryptography are numerous, where they are typically used to force malicious parties to behave according to a predetermined protocol. In addition, zero-knowledge proofs serve as an excellent bench-mark for the study of various problems regarding cryptographic protocols. The first part of this tutorial reviews the basic definitional approach and its variants as well as the main results regarding the power of zero-knowledge proofs. The second part reviews several advanced topics including (1) the composeability of zero-knowledge proofs and (2) the use of the adversary's program within the proof of security (i.e., non-black-box simulation).