Memory-Hard Functions: When Theory Meets Practice