Golang implementation ANProto: the Authenticated and Non-networked protocol or ANother protocol
at main 68 lines 1.6 kB view raw
1package goan 2 3import ( 4 "crypto/ed25519" 5 "crypto/sha256" 6 "encoding/base64" 7 "errors" 8 "strconv" 9 "time" 10) 11 12// Gen returns base64(publicKey)+base64(secretKey) 13func Gen() (string, error) { 14 pub, priv, err := ed25519.GenerateKey(nil) 15 if err != nil { 16 return "", err 17 } 18 pubB := base64.StdEncoding.EncodeToString(pub) 19 privB := base64.StdEncoding.EncodeToString(priv) 20 return pubB + privB, nil 21} 22 23func Hash(d string) string { 24 h := sha256.Sum256([]byte(d)) 25 return base64.StdEncoding.EncodeToString(h[:]) 26} 27 28func Sign(h string, k string) (string, error) { 29 if len(k) < 44+88 { 30 return "", errors.New("invalid key length") 31 } 32 pubB := k[:44] 33 privB := k[44:] 34 priv, err := base64.StdEncoding.DecodeString(privB) 35 if err != nil { 36 return "", err 37 } 38 msg := []byte(strconv.FormatInt(time.Now().UnixNano()/1e6, 10) + h) 39 sig := ed25519.Sign(priv, msg) 40 signed := append(sig, msg...) 41 signedB := base64.StdEncoding.EncodeToString(signed) 42 return pubB + signedB, nil 43} 44 45func Open(m string) (string, error) { 46 if len(m) < 44 { 47 return "", errors.New("invalid message") 48 } 49 pubB := m[:44] 50 signedB := m[44:] 51 signed, err := base64.StdEncoding.DecodeString(signedB) 52 if err != nil { 53 return "", err 54 } 55 if len(signed) < ed25519.SignatureSize { 56 return "", errors.New("signed message too short") 57 } 58 sig := signed[:ed25519.SignatureSize] 59 msg := signed[ed25519.SignatureSize:] 60 pub, err := base64.StdEncoding.DecodeString(pubB) 61 if err != nil { 62 return "", err 63 } 64 if !ed25519.Verify(pub, msg, sig) { 65 return "", errors.New("signature verification failed") 66 } 67 return string(msg), nil 68}