public PrivateKey decodePrivateKey(byte[] k) {
      // magic
      if (k[0] != Registry.MAGIC_RAW_SRP_PRIVATE_KEY[0]
            || k[1] != Registry.MAGIC_RAW_SRP_PRIVATE_KEY[1]
            || k[2] != Registry.MAGIC_RAW_SRP_PRIVATE_KEY[2]
            || k[3] != Registry.MAGIC_RAW_SRP_PRIVATE_KEY[3]) {
         throw new IllegalArgumentException("magic");
      }

      // version
      if (k[4] != 0x01) {
         throw new IllegalArgumentException("version");
      }
      int i = 5;

      int l;
      byte[] buffer;

      // N
      l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 | (k[i++] & 0xFF);
      buffer = new byte[l];
      System.arraycopy(k, i, buffer, 0, l);
      i += l;
      BigInteger N = new BigInteger(1, buffer);

      // g
      l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 | (k[i++] & 0xFF);
      buffer = new byte[l];
      System.arraycopy(k, i, buffer, 0, l);
      i += l;
      BigInteger g = new BigInteger(1, buffer);

      // x
      l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 | (k[i++] & 0xFF);
      buffer = new byte[l];
      System.arraycopy(k, i, buffer, 0, l);
      i += l;
      BigInteger x = new BigInteger(1, buffer);

      // v
      l = k[i++];
      if (l == 0x01) {
         l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 | (k[i++] & 0xFF);
         buffer = new byte[l];
         System.arraycopy(k, i, buffer, 0, l);
         i += l;
         BigInteger v = new BigInteger(1, buffer);

         return new SRPPrivateKey(N, g, x, v);
      } else {
         return new SRPPrivateKey(N, g, x);
      }
   }