Change 'cryptmethod' from a number to a string option.  Make it global-local.
diff --git a/src/buffer.c b/src/buffer.c
index e7fecd7..a8808d3 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1756,6 +1756,9 @@
 #if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
     clear_string_option(&buf->b_p_bexpr);
 #endif
+#if defined(FEAT_CRYPT)
+    clear_string_option(&buf->b_p_cm);
+#endif
 #if defined(FEAT_EVAL)
     clear_string_option(&buf->b_p_fex);
 #endif
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index b56fb67..2d1a893 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -11189,7 +11189,7 @@
 ex_X(eap)
     exarg_T	*eap UNUSED;
 {
-    if (curbuf->b_p_cm == 0 || blowfish_self_test() == OK)
+    if (get_crypt_method(curbuf) == 0 || blowfish_self_test() == OK)
 	(void)get_crypt_key(TRUE, TRUE);
 }
 #endif
diff --git a/src/fileio.c b/src/fileio.c
index d467eba..aa3143e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -63,7 +63,7 @@
 static void check_marks_read __ARGS((void));
 #endif
 #ifdef FEAT_CRYPT
-static int get_crypt_method __ARGS((char *ptr, int len));
+static int crypt_method_from_magic __ARGS((char *ptr, int len));
 static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, off_t *filesizep, int newfile, char_u *fname, int *did_ask));
 #endif
 #ifdef UNIX
@@ -2855,7 +2855,7 @@
  * Returns -1 when no encryption used.
  */
     static int
-get_crypt_method(ptr, len)
+crypt_method_from_magic(ptr, len)
     char  *ptr;
     int   len;
 {
@@ -2892,11 +2892,11 @@
     char_u	*fname;		/* file name to display */
     int		*did_ask;	/* flag: whether already asked for key */
 {
-    int method = get_crypt_method((char *)ptr, *sizep);
+    int method = crypt_method_from_magic((char *)ptr, *sizep);
 
     if (method >= 0)
     {
-	curbuf->b_p_cm = method;
+	set_crypt_method(curbuf, method);
 	if (method > 0)
 	    (void)blowfish_self_test();
 	if (cryptkey == NULL && !*did_ask)
@@ -2968,11 +2968,11 @@
 
     if (fread(buffer, CRYPT_MAGIC_LEN, 1, fp) != 1)
 	return FAIL;
-    method = get_crypt_method((char *)buffer,
+    method = crypt_method_from_magic((char *)buffer,
 					CRYPT_MAGIC_LEN +
 					CRYPT_SEED_LEN_MAX +
 					CRYPT_SALT_LEN_MAX);
-    if (method < 0 || method != curbuf->b_p_cm)
+    if (method < 0 || method != get_crypt_method(curbuf))
 	return FAIL;
 
     crypt_push_state();
@@ -3003,8 +3003,8 @@
     int   *lenp;
 {
     char_u  *header;
-    int	    seed_len = crypt_seed_len[buf->b_p_cm];
-    int     salt_len = crypt_salt_len[buf->b_p_cm];
+    int	    seed_len = crypt_seed_len[get_crypt_method(buf)];
+    int     salt_len = crypt_salt_len[get_crypt_method(buf)];
     char_u  *salt;
     char_u  *seed;
 
@@ -3013,10 +3013,10 @@
     if (header != NULL)
     {
 	crypt_push_state();
-	use_crypt_method = buf->b_p_cm;  /* select pkzip or blowfish */
+	use_crypt_method = get_crypt_method(buf);  /* select zip or blowfish */
 	vim_strncpy(header, (char_u *)crypt_magic[use_crypt_method],
 							     CRYPT_MAGIC_LEN);
-	if (buf->b_p_cm == 0)
+	if (use_crypt_method == 0)
 	    crypt_init_keys(buf->b_p_key);
 	else
 	{
diff --git a/src/memline.c b/src/memline.c
index 0268087..0f7b1d1 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -441,7 +441,7 @@
 	b0p->b0_id[1] = BLOCK0_ID1;
     else
     {
-	if (buf->b_p_cm == 0)
+	if (get_crypt_method(buf) == 0)
 	    b0p->b0_id[1] = BLOCK0_ID1_C0;
 	else
 	{
@@ -458,8 +458,8 @@
  * Will apply this to the swapfile.
  * "old_key" is the previous key.  It is equal to buf->b_p_key when
  * 'cryptmethod' is changed.
- * "old_cm" is the previous 'cryptmethod'.  It is equal to buf->b_p_cm when
- * 'key' is changed.
+ * "old_cm" is the previous 'cryptmethod'.  It is equal to the current
+ * 'cryptmethod' when 'key' is changed.
  */
     void
 ml_set_crypt_key(buf, old_key, old_cm)
@@ -1250,12 +1250,13 @@
 
 #ifdef FEAT_CRYPT
     if (b0p->b0_id[1] == BLOCK0_ID1_C0)
-	buf->b_p_cm = b0_cm = 0;
+	b0_cm = 0;
     else if (b0p->b0_id[1] == BLOCK0_ID1_C1)
     {
-	buf->b_p_cm = b0_cm = 1;
+	b0_cm = 1;
 	mch_memmove(mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
     }
+    set_crypt_method(buf, b0_cm);
 #else
     if (b0p->b0_id[1] != BLOCK0_ID1)
     {
@@ -4908,7 +4909,7 @@
     }
     else
     {
-	method = buf->b_p_cm;
+	method = get_crypt_method(buf);
 	key = buf->b_p_key;
 	seed = mfp->mf_seed;
     }
diff --git a/src/misc2.c b/src/misc2.c
index 1eb4e8a..9327e89 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -3751,6 +3751,41 @@
 static int saved_crypt_method;
 
 /*
+ * Return int value for crypt method string:
+ * 0 for "zip", the old method.  Also for any non-valid value.
+ * 1 for "blowfish".
+ */
+    int
+crypt_method_from_string(s)
+    char_u  *s;
+{
+    return *s == 'b' ? 1 : 0;
+}
+
+/*
+ * Get the crypt method for buffer "buf" as a number.
+ */
+    int
+get_crypt_method(buf)
+    buf_T *buf;
+{
+    return crypt_method_from_string(*buf->b_p_cm == NUL ? p_cm : buf->b_p_cm);
+}
+
+/*
+ * Set the crypt method for buffer "buf" to "method" using the int value as
+ * returned by crypt_method_from_string().
+ */
+    void
+set_crypt_method(buf, method)
+    buf_T   *buf;
+    int	    method;
+{
+    free_string_option(buf->b_p_cm);
+    buf->b_p_cm = vim_strsave((char_u *)(method == 0 ? "zip" : "blowfish"));
+}
+
+/*
  * Prepare for initializing encryption.  If already doing encryption then save
  * the state.
  * Must always be called symmetrycally with crypt_pop_state().
diff --git a/src/option.c b/src/option.c
index 27a82fd..63c0f2e 100644
--- a/src/option.c
+++ b/src/option.c
@@ -77,7 +77,7 @@
 #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
 # define PV_CINW	OPT_BUF(BV_CINW)
 #endif
-#define PV_CM		OPT_BUF(BV_CM)
+#define PV_CM		OPT_BOTH(OPT_BUF(BV_CM))
 #ifdef FEAT_FOLDING
 # define PV_CMS		OPT_BUF(BV_CMS)
 #endif
@@ -287,9 +287,6 @@
 #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
 static char_u	*p_cinw;
 #endif
-#ifdef FEAT_CRYPT
-static long	p_cm;
-#endif
 #ifdef FEAT_COMMENTS
 static char_u	*p_com;
 #endif
@@ -866,13 +863,15 @@
 			    (char_u *)&p_cpo, PV_NONE,
 			    {(char_u *)CPO_VI, (char_u *)CPO_VIM}
 			    SCRIPTID_INIT},
-    {"cryptmethod", "cm",   P_NUM|P_VI_DEF|P_VIM,
+    {"cryptmethod", "cm",   P_STRING|P_ALLOCED|P_VI_DEF,
 #ifdef FEAT_CRYPT
 			    (char_u *)&p_cm, PV_CM,
+			    {(char_u *)"zip", (char_u *)0L}
 #else
 			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
 #endif
-			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+			    SCRIPTID_INIT},
     {"cscopepathcomp", "cspc", P_NUM|P_VI_DEF|P_VIM,
 #ifdef FEAT_CSCOPE
 			    (char_u *)&p_cspc, PV_NONE,
@@ -2915,6 +2914,9 @@
 static char *(p_bg_values[]) = {"light", "dark", NULL};
 static char *(p_nf_values[]) = {"octal", "hex", "alpha", NULL};
 static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
+#ifdef FEAT_CRYPT
+static char *(p_cm_values[]) = {"zip", "blowfish", NULL};
+#endif
 #ifdef FEAT_CMDL_COMPL
 static char *(p_wop_values[]) = {"tagfile", NULL};
 #endif
@@ -5215,6 +5217,9 @@
 #if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
     check_string_option(&buf->b_p_bexpr);
 #endif
+#if defined(FEAT_CRYPT)
+    check_string_option(&buf->b_p_cm);
+#endif
 #if defined(FEAT_EVAL)
     check_string_option(&buf->b_p_fex);
 #endif
@@ -5998,7 +6003,57 @@
 # endif
 	if (STRCMP(curbuf->b_p_key, oldval) != 0)
 	    /* Need to update the swapfile. */
-	    ml_set_crypt_key(curbuf, oldval, curbuf->b_p_cm);
+	    ml_set_crypt_key(curbuf, oldval, get_crypt_method(curbuf));
+    }
+
+    else if (gvarp == &p_cm)
+    {
+	if (opt_flags & OPT_LOCAL)
+	    p = curbuf->b_p_cm;
+	else
+	    p = p_cm;
+	if (check_opt_strings(p, p_cm_values, TRUE) != OK)
+	    errmsg = e_invarg;
+	else if (get_crypt_method(curbuf) > 0 && blowfish_self_test() == FAIL)
+	    errmsg = e_invarg;
+	else
+	{
+	    /* When setting the global value to empty, make it "zip". */
+	    if (*p_cm == NUL)
+	    {
+		if (new_value_alloced)
+		    free_string_option(p_cm);
+		p_cm = vim_strsave((char_u *)"zip");
+		new_value_alloced = TRUE;
+	    }
+
+	    /* Need to update the swapfile when the effective method changed.
+	     * Set "s" to the effective old value, "p" to the effective new
+	     * method and compare. */
+	    if ((opt_flags & OPT_LOCAL) && *oldval == NUL)
+		s = p_cm;  /* was previously using the global value */
+	    else
+		s = oldval;
+	    if (*curbuf->b_p_cm == NUL)
+		p = p_cm;  /* is now using the global value */
+	    else
+		p = curbuf->b_p_cm;
+	    if (STRCMP(s, p) != 0)
+		ml_set_crypt_key(curbuf, curbuf->b_p_key,
+						 crypt_method_from_string(s));
+
+	    /* If the global value changes need to update the swapfile for all
+	     * buffers using that value. */
+	    if ((opt_flags & OPT_GLOBAL) && STRCMP(p_cm, oldval) != 0)
+	    {
+		buf_T	*buf;
+
+		for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+		    if (buf != curbuf && *buf->b_p_cm == NUL)
+			ml_set_crypt_key(buf, buf->b_p_key,
+					    crypt_method_from_string(oldval));
+	    }
+	}
     }
 #endif
 
@@ -8048,28 +8103,6 @@
 
 #endif
 
-#ifdef FEAT_CRYPT
-    else if (pp == &curbuf->b_p_cm)
-    {
-	if (curbuf->b_p_cm < 0)
-	{
-	    errmsg = e_positive;
-	    curbuf->b_p_cm = old_value;
-	}
-	if (curbuf->b_p_cm > 1)
-	{
-	    errmsg = e_invarg;
-	    curbuf->b_p_cm = old_value;
-	}
-	if (curbuf->b_p_cm > 0 && blowfish_self_test() == FAIL)
-	    curbuf->b_p_cm = old_value;
-
-	if (curbuf->b_p_cm != old_value && *curbuf->b_p_key != NUL)
-	    /* Need to update the swapfile. */
-	    ml_set_crypt_key(curbuf, curbuf->b_p_key, old_value);
-    }
-#endif
-
 #ifdef FEAT_WINDOWS
     /* (re)set last window status line */
     else if (pp == &p_ls)
@@ -9383,6 +9416,9 @@
 #if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
 	    case PV_BEXPR: return (char_u *)&(curbuf->b_p_bexpr);
 #endif
+#if defined(FEAT_CRYPT)
+	    case PV_CM:	  return (char_u *)&(curbuf->b_p_cm);
+#endif
 #ifdef FEAT_STL_OPT
 	    case PV_STL:  return (char_u *)&(curwin->w_p_stl);
 #endif
@@ -9442,6 +9478,10 @@
 	case PV_BEXPR:	return *curbuf->b_p_bexpr != NUL
 				    ? (char_u *)&(curbuf->b_p_bexpr) : p->var;
 #endif
+#if defined(FEAT_CRYPT)
+	case PV_CM:	return *curbuf->b_p_cm != NUL
+				    ? (char_u *)&(curbuf->b_p_cm) : p->var;
+#endif
 #ifdef FEAT_STL_OPT
 	case PV_STL:	return *curwin->w_p_stl != NUL
 				    ? (char_u *)&(curwin->w_p_stl) : p->var;
@@ -9525,9 +9565,6 @@
 	case PV_CINK:	return (char_u *)&(curbuf->b_p_cink);
 	case PV_CINO:	return (char_u *)&(curbuf->b_p_cino);
 #endif
-#ifdef FEAT_CRYPT
-	case PV_CM:	return (char_u *)&(curbuf->b_p_cm);
-#endif
 #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
 	case PV_CINW:	return (char_u *)&(curbuf->b_p_cinw);
 #endif
@@ -9994,6 +10031,9 @@
 #if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
 	    buf->b_p_bexpr = empty_option;
 #endif
+#if defined(FEAT_CRYPT)
+	    buf->b_p_cm = empty_option;
+#endif
 #ifdef FEAT_PERSISTENT_UNDO
 	    buf->b_p_udf = p_udf;
 #endif
diff --git a/src/option.h b/src/option.h
index 1693622..817e337 100644
--- a/src/option.h
+++ b/src/option.h
@@ -333,6 +333,9 @@
 #ifdef FEAT_WILDIGN
 EXTERN char_u	*p_bsk;		/* 'backupskip' */
 #endif
+#ifdef FEAT_CRYPT
+EXTERN char_u	*p_cm;		/* 'cryptmethod' */
+#endif
 #ifdef FEAT_BEVAL
 EXTERN long	p_bdlay;	/* 'balloondelay' */
 EXTERN int	p_beval;	/* 'ballooneval' */
diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro
index 8d3397f..3fa0c9b 100644
--- a/src/proto/misc2.pro
+++ b/src/proto/misc2.pro
@@ -80,6 +80,9 @@
 char_u *parse_shape_opt __ARGS((int what));
 int get_shape_idx __ARGS((int mouse));
 void update_mouseshape __ARGS((int shape_idx));
+int crypt_method_from_string __ARGS((char_u *s));
+int get_crypt_method __ARGS((buf_T *buf));
+void set_crypt_method __ARGS((buf_T *buf, int method));
 void crypt_push_state __ARGS((void));
 void crypt_pop_state __ARGS((void));
 void crypt_encode __ARGS((char_u *from, size_t len, char_u *to));
diff --git a/src/structs.h b/src/structs.h
index ebcc3cf..42b1d2a 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1450,9 +1450,6 @@
 #ifdef FEAT_INS_EXPAND
     char_u	*b_p_cpt;	/* 'complete' */
 #endif
-#ifdef FEAT_CRYPT
-    long	b_p_cm;		/* 'cryptmethod' */
-#endif
 #ifdef FEAT_COMPL_FUNC
     char_u	*b_p_cfu;	/* 'completefunc' */
     char_u	*b_p_ofu;	/* 'omnifunc' */
@@ -1574,6 +1571,9 @@
     char_u	*b_p_bexpr;	/* 'balloonexpr' local value */
     long_u	b_p_bexpr_flags;/* flags for 'balloonexpr' */
 #endif
+#ifdef FEAT_CRYPT
+    char_u	*b_p_cm;	/* 'cryptmethod' */
+#endif
 
     /* When a buffer is created, it starts without a swap file.  b_may_swap is
      * then set to indicate that a swap file may be opened later.  It is reset
diff --git a/src/testdir/test71.in b/src/testdir/test71.in
index 56dee55..7de2930 100644
--- a/src/testdir/test71.in
+++ b/src/testdir/test71.in
Binary files differ