[submodule "src/golang.org/x/crypto"]
path = src/golang.org/x/crypto
url = https://go.googlesource.com/crypto
-[submodule "src/github.com/magical/argon2"]
- path = src/github.com/magical/argon2
- url = https://github.com/magical/argon2.git
[submodule "src/github.com/dchest/blake2b"]
path = src/github.com/dchest/blake2b
url = https://github.com/dchest/blake2b.git
[submodule "src/github.com/go-yaml/yaml"]
path = src/github.com/go-yaml/yaml
url = https://github.com/go-yaml/yaml.git
+[submodule "src/cypherpunks.ru/balloon"]
+ path = src/cypherpunks.ru/balloon
+ url = git://git.cypherpunks.ru/balloon.git
@item DH elliptic-curve point encoding for public keys
@url{http://elligator.cr.yp.to/, Elligator}.
@item Verifier password hashing algorithm
- @url{https://password-hashing.net/#argon2, Argon2d}.
+ @url{https://crypto.stanford.edu/balloon/, Balloon hashing} based
+ on BLAKE2b-256.
@item Encryptionless confidentiality preserving encoding
@url{http://people.csail.mit.edu/rivest/chaffing-980701.txt,
Chaffing-and-Winnowing} (two Poly1305 MACs for each bit of message)
@verbatim
client% ./utils/newclient.sh Alice
Passphrase:
-Your client verifier is: $argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg
+Your client verifier is: $balloon$s=32768,t=16,p=2$bwR5VjeCYIQaa8SeaI3rqg
Place the following YAML configuration entry on the server's side:
Alice:
up: /path/to/up.sh
iface: or TAP interface name
- verifier: $argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10
+ verifier: $balloon$s=32768,t=16,p=2$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10
@end verbatim
@strong{Prepare the server}. Add this entry to @file{peers.yaml}
@verbatim
Alice:
iface: tap10
- verifier: $argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10
+ verifier: $balloon$s=32768,t=16,p=2$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10
@end verbatim
@strong{Prepare network on GNU/Linux IPv4 server}:
@strong{Run client daemon itself}:
@verbatim
client% govpn-client \
- -verifier '$argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg' \
+ -verifier '$balloon$s=32768,t=16,p=2$bwR5VjeCYIQaa8SeaI3rqg' \
-iface tap10 \
-remote 192.168.0.1:1194
@end verbatim
client% ifconfig tap10 inet6 fc00::2/96 up
client% route -6 add default fc00::1
client% govpn-client \
- -verifier '$argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg' \
+ -verifier '$balloon$s=32768,t=16,p=2$bwR5VjeCYIQaa8SeaI3rqg' \
-iface tap10 \
-remote "[fe80::1%me0]":1194
@end verbatim
@item @code{github.com/bigeagle/water} @tab GNU/Linux @tab BSD 3-Clause
@item @code{github.com/dchest/blake2b} @tab All @tab CC0 1.0
@item @code{github.com/go-yaml/yaml} @tab All @tab LGPLv3 and MIT
-@item @code{github.com/magical/argon2} @tab All @tab BSD 2-Clause
@item @code{golang.org/x/crypto} @tab All @tab BSD 3-Clause
@end multitable
@node Новости
@section Новости
+@node Релиз 6.0
+@subsection Релиз 6.0
+@itemize
+@item Argon2d заменён на Balloon хэширование. Найденные Argon2
+библиотеки, написанные полностью на Go, имеют различные проблемы. Более
+того, Argon2i должен был быть использован вместо Argon2d, но у него есть
+возможные @url{http://eprint.iacr.org/2016/027, криптографические
+недостатки}. Поэтому он заменён на гораздо более простое (и, похоже,
+даже криптографически лучшее)
+@url{https://crypto.stanford.edu/balloon/, Balloon хэширование}.
+@end itemize
+
@node Релиз 5.10
@subsection Релиз 5.10
@itemize
See also this page @ref{Новости, on russian}.
+@node Release 6.0
+@section Release 6.0
+@itemize
+@item Argon2d is replaced with Balloon hashing. Found Argon2 libraries
+written on pure Go have various problems. Moreover Argon2i should be
+used instead, but it has some possible
+@url{http://eprint.iacr.org/2016/027, cryptographic defects}. So it is
+replaced with much more simpler (and seems even cryptographically
+better) @url{https://crypto.stanford.edu/balloon/, Balloon hashing}.
+@end itemize
+
@node Release 5.10
@section Release 5.10
@itemize
noise: No <-- OPTIONAL noise enabler
cpr: 64 <-- OPTIONAL constant packet rate, KiB/sec
encless: No <-- OPTIONAL Encryptionless mode
- verifier: $argon2d... <-- verifier received from client
+ verifier: $baloon... <-- verifier received from client
[...]
@end verbatim
@verbatim
% ./utils/newclient.sh Alice
[...]
-Your client verifier is: $argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg
+Your client verifier is: $balloon$s=32768,t=16,p=2$bwR5VjeCYIQaa8SeaI3rqg
Place the following YAML configuration entry on the server's side:
Alice:
up: /path/to/up.sh
iface: or TAP interface name
- verifier: $argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10
+ verifier: $balloon$s=32768,t=16,p=2$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10
@end verbatim
Example configuration file:
@verbatim
stargrave:
iface: tap0
- verifier: $argon2d$m=4096,t=128,p=1$VMirzcshcHuG2V4jhUsEjw$X5fC07L8k61h3S1Oro/rC76+m0oGDTA9Bq+aWJ1uOgY
+ verifier: $balloon$s=32768,t=16,p=2$VMirzcshcHuG2V4jhUsEjw$X5fC07L8k61h3S1Oro/rC76+m0oGDTA9Bq+aWJ1uOgY
slow:
iface: tap1
encless: Yes
mtu: 9000
cpr: 384
- verifier: $argon2d$m=4096,t=128,p=1$YbIA5garDqCOhtI/2EZVNg$gOo5vcEGynmpeepNscwclicfZsWxzgYFRLbgG21EZ1U
+ verifier: $balloon$s=32768,t=16,p=2$YbIA5garDqCOhtI/2EZVNg$gOo5vcEGynmpeepNscwclicfZsWxzgYFRLbgG21EZ1U
@end verbatim
@item @code{github.com/bigeagle/water} @tab @url{git://git.cypherpunks.ru/water.git}
@item @code{github.com/dchest/blake2b} @tab @url{git://git.cypherpunks.ru/blake2b.git}
@item @code{github.com/go-yaml/yaml} @tab @url{git://git.cypherpunks.ru/yaml.git}
-@item @code{github.com/magical/argon2} @tab @url{git://git.cypherpunks.ru/argon2.git}
@item @code{golang.org/x/crypto} @tab @url{git://git.cypherpunks.ru/crypto.git}
@end multitable
@item @url{https://www.cs.columbia.edu/~smb/papers/aeke.pdf, Augmented Encrypted Key Exchange}: a Password-Based Protocol Secure Against Dictionary Attacks and Password File Compromise @copyright{} Steven M. Belloving, Michael Merrit.
@item @email{watsonbladd@@gmail.com, Watson Ladd} for suggestion of @url{http://elligator.cr.yp.to/, Elligator} encoding.
@item @url{https://password-hashing.net/#argon2, Password Hashing Competition for Argon2}.
+@item @url{https://crypto.stanford.edu/balloon/, Balloon hashing}.
@item @url{http://people.csail.mit.edu/rivest/chaffing-980701.txt, Chaffing and Winnowing: Confidentiality without Encryption} @copyright{} Ronald L. Rivest
@item @email{wzyboy@@wzyboy.org, Zhuoyun Wei} for @url{https://aur.archlinux.org/packages/govpn/, AUR} port maintaining and his documentation related fixes.
@end itemize
@verbatim
% govpn-verifier
Passphrase:[hello world]
-$argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10
-$argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg
+$balloon$s=32768,t=16,p=2$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10
+$balloon$s=32768,t=16,p=2$bwR5VjeCYIQaa8SeaI3rqg
@end verbatim
First line is the verifier for the server side. Second line is for the
option with the path to verifier file:
@verbatim
-% govpn-verifier -verifier '$argon2d...'
+% govpn-verifier -verifier '$balloon...'
Passphrase:[hello world]
true
@end verbatim
its verifying).
@verbatim
-SOURCE = Argon2d(m, t, p, SALT=PeerId, PASSWORD)
+SOURCE = Balloon(PASSWORD, SALT=PeerId, sCost, tCost, pJobs)
PUB, PRIV = Ed25519.Generate(SOURCE)
@end verbatim
+Balloon hashing uses BLAKE2b-256 hash. Space cost (sCost), time cost
+(tCost) and number of parallel jobs (pJobs) are specific to Balloon
+implementation.
+
Verifier is serialized representation of public data above:
@verbatim
-$argon2d$m=m,t=t,p=p$Base64(SALT)$Base64(PUB)
+$balloon$s=s,t=t,p=p$Base64(SALT)$Base64(PUB)
@end verbatim
-m, t and p parameters are Argon2d-specific: memory, iterations and
-parallelizm parameters.
-
Server stores and knows only verifier. Client can compute the whole
keypair every time he makes handshake.
--- /dev/null
+Subproject commit 9e7f63092012aa91a6690d93f00f5bc476e4d3b5
var (
keyPath = flag.String("key", "", "Path to passphrase file")
verifier = flag.String("verifier", "", "Optional verifier")
- mOpt = flag.Int("m", govpn.DefaultM, "Argon2d memory parameter (KiBs)")
- tOpt = flag.Int("t", govpn.DefaultT, "Argon2d iteration parameter")
- pOpt = flag.Int("p", govpn.DefaultP, "Argon2d parallelizm parameter")
+ sOpt = flag.Int("s", govpn.DefaultS, "Balloon space cost")
+ tOpt = flag.Int("t", govpn.DefaultT, "Balloon time cost")
+ pOpt = flag.Int("p", govpn.DefaultP, "Balloon parallel jobs")
egdPath = flag.String("egd", "", "Optional path to EGD socket")
version = flag.Bool("version", false, "Print version information")
warranty = flag.Bool("warranty", false, "Print warranty information")
log.Fatalln(err)
}
pid := govpn.PeerId(*id)
- v := govpn.VerifierNew(*mOpt, *tOpt, *pOpt, &pid)
+ v := govpn.VerifierNew(*sOpt, *tOpt, *pOpt, &pid)
v.PasswordApply(key)
fmt.Println(v.LongForm())
fmt.Println(v.ShortForm())
"os"
"strings"
+ "cypherpunks.ru/balloon"
"github.com/agl/ed25519"
- "github.com/magical/argon2"
+ "github.com/dchest/blake2b"
"golang.org/x/crypto/ssh/terminal"
)
const (
- DefaultM = 1 << 12
- DefaultT = 1 << 7
- DefaultP = 1
+ DefaultS = 1 << 20 / 32
+ DefaultT = 1 << 4
+ DefaultP = 2
)
type Verifier struct {
- M int
+ S int
T int
P int
Id *PeerId
// Generate new verifier for given peer, with specified password and
// hashing parameters.
-func VerifierNew(m, t, p int, id *PeerId) *Verifier {
- return &Verifier{M: m, T: t, P: p, Id: id}
+func VerifierNew(s, t, p int, id *PeerId) *Verifier {
+ return &Verifier{S: s, T: t, P: p, Id: id}
}
// Apply the password: create Ed25519 keypair based on it, save public
// key in verifier.
func (v *Verifier) PasswordApply(password string) *[ed25519.PrivateKeySize]byte {
- r, err := argon2.Key([]byte(password), v.Id[:], v.T, v.P, int64(v.M), 32)
- if err != nil {
- log.Fatalln("Unable to apply Argon2d", err)
- }
+ r := balloon.H(blake2b.New256, []byte(password), v.Id[:], v.S, v.T, v.P)
defer SliceZero(r)
src := bytes.NewBuffer(r)
pub, prv, err := ed25519.GenerateKey(src)
// Parse either short or long verifier form.
func VerifierFromString(input string) (*Verifier, error) {
- s := strings.Split(input, "$")
- if len(s) < 4 || s[1] != "argon2d" {
+ ss := strings.Split(input, "$")
+ if len(ss) < 4 || ss[1] != "balloon" {
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)
+ var s, t, p int
+ n, err := fmt.Sscanf(ss[2], "s=%d,t=%d,p=%d", &s, &t, &p)
if n != 3 || err != nil {
return nil, errors.New("Invalid verifier parameters")
}
- salt, err := base64.RawStdEncoding.DecodeString(s[3])
+ salt, err := base64.RawStdEncoding.DecodeString(ss[3])
if err != nil {
return nil, err
}
- v := Verifier{M: m, T: t, P: p}
+ v := Verifier{S: s, 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 len(ss) == 5 {
+ pub, err := base64.RawStdEncoding.DecodeString(ss[4])
if err != nil {
return nil, err
}
// 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[:]),
+ "$balloon$s=%d,t=%d,p=%d$%s",
+ v.S, v.T, v.P, base64.RawStdEncoding.EncodeToString(v.Id[:]),
)
}
+++ /dev/null
-Subproject commit 190e3cf208e185668db6aa048e4985b7b7b4d890
src/github.com/bigeagle/water
src/github.com/dchest/blake2b
src/github.com/go-yaml/yaml
- src/github.com/magical/argon2
src/golang.org/x/crypto
"
for repo in $repos; do