+ v.Pub = pub
+ return prv
+}
+
+// Parse either short or long verifier form.
+func VerifierFromString(input string) (*Verifier, error) {
+ s := strings.Split(input, "$")
+ if !(len(s) != 4 || len(s) != 5) || s[1] != "argon2d" {
+ return nil, errors.New("Invalid verifier structure")
+ }
+ var m, t, p int
+ n, err := fmt.Sscanf(s[2], "m=%d,t=%d,p=%d", &m, &t, &p)
+ if n != 3 || err != nil {
+ return nil, errors.New("Invalid verifier parameters")
+ }
+ salt, err := base64.RawStdEncoding.DecodeString(s[3])
+ if err != nil {
+ return nil, err
+ }
+ v := Verifier{M: m, T: t, P: p}
+ id := new([IDSize]byte)
+ copy(id[:], salt)
+ pid := PeerId(*id)
+ v.Id = &pid
+ if len(s) == 5 {
+ pub, err := base64.RawStdEncoding.DecodeString(s[4])
+ if err != nil {
+ return nil, err
+ }
+ v.Pub = new([ed25519.PublicKeySize]byte)
+ copy(v.Pub[:], pub)
+ }
+ return &v, nil
+}
+
+// Short verifier string form -- it is useful for the client.
+// Does not include public key.
+func (v *Verifier) ShortForm() string {
+ return fmt.Sprintf(
+ "$argon2d$m=%d,t=%d,p=%d$%s",
+ v.M, v.T, v.P, base64.RawStdEncoding.EncodeToString(v.Id[:]),
+ )
+}
+
+// Long verifier string form -- it is useful for the server.
+// Includes public key.
+func (v *Verifier) LongForm() string {
+ return fmt.Sprintf(
+ "%s$%s", v.ShortForm(),
+ base64.RawStdEncoding.EncodeToString(v.Pub[:]),
+ )