mirror of
https://gogs.blitter.com/RLabs/xs
synced 2024-08-14 10:26:42 +00:00
Added NEWHOPE and NEWHOPE_SIMPLE KEM algs
Fixed some -h typos, missing H_SHA512 option randReader seed time.Now().UnixNano() Signed-off-by: Russ Magee <rmagee@gmail.com>
This commit is contained in:
parent
a53ec4ac2d
commit
f09d6bbfef
5 changed files with 213 additions and 14 deletions
|
@ -10,4 +10,4 @@ package hkexsh
|
|||
// common constants for the HKExSh
|
||||
|
||||
// Version string returned by tools
|
||||
const Version = "0.8.0 (NO WARRANTY)"
|
||||
const Version = "0.8.1 (NO WARRANTY)"
|
||||
|
|
|
@ -20,8 +20,8 @@ const (
|
|||
KEX_KYBER768
|
||||
KEX_KYBER1024
|
||||
KEX_resvd11
|
||||
KEX_resvd12
|
||||
KEX_resvd13
|
||||
KEX_NEWHOPE
|
||||
KEX_NEWHOPE_SIMPLE // 'NewHopeLP-Simple' - https://eprint.iacr.org/2016/1157
|
||||
KEX_resvd14
|
||||
KEX_resvd15
|
||||
)
|
||||
|
|
|
@ -49,6 +49,7 @@ import (
|
|||
"blitter.com/go/herradurakex"
|
||||
"blitter.com/go/hkexsh/logger"
|
||||
kyber "git.schwanenlied.me/yawning/kyber.git"
|
||||
newhope "git.schwanenlied.me/yawning/newhope.git"
|
||||
)
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
@ -197,6 +198,12 @@ func getkexalgnum(extensions ...string) (k KEXAlg) {
|
|||
case "KEX_KYBER1024":
|
||||
k = KEX_KYBER1024
|
||||
break //out of for
|
||||
case "KEX_NEWHOPE":
|
||||
k = KEX_NEWHOPE
|
||||
break //out of for
|
||||
case "KEX_NEWHOPE_SIMPLE":
|
||||
k = KEX_NEWHOPE_SIMPLE
|
||||
break //out of for
|
||||
}
|
||||
}
|
||||
return
|
||||
|
@ -227,12 +234,16 @@ func _new(kexAlg KEXAlg, conn *net.Conn) (hc *Conn, e error) {
|
|||
case KEX_HERRADURA1024:
|
||||
fallthrough
|
||||
case KEX_HERRADURA2048:
|
||||
log.Printf("[KEx alg %d accepted]\n", kexAlg)
|
||||
fallthrough
|
||||
case KEX_KYBER512:
|
||||
fallthrough
|
||||
case KEX_KYBER768:
|
||||
fallthrough
|
||||
case KEX_KYBER1024:
|
||||
fallthrough
|
||||
case KEX_NEWHOPE:
|
||||
fallthrough
|
||||
case KEX_NEWHOPE_SIMPLE:
|
||||
log.Printf("[KEx alg %d accepted]\n", kexAlg)
|
||||
default:
|
||||
// UNREACHABLE: _getkexalgnum() guarantees a valid KEX value
|
||||
|
@ -276,7 +287,7 @@ func (hc *Conn) applyConnExtensions(extensions ...string) {
|
|||
}
|
||||
|
||||
// randReader wraps rand.Read() in a struct that implements io.Reader
|
||||
// for use by the Kyber KEM methods.
|
||||
// for use by the Kyber and NEWHOPE/NEWHOPE_SIMPLE KEM methods.
|
||||
type randReader struct {
|
||||
}
|
||||
|
||||
|
@ -285,11 +296,101 @@ func (r randReader) Read(b []byte) (n int, e error) {
|
|||
return
|
||||
}
|
||||
|
||||
func NewHopeDialSetup(c io.ReadWriter, hc *Conn) (err error) {
|
||||
// Send hkexnet.Conn parameters to remote side
|
||||
|
||||
// Alice, step 1: Generate a key pair.
|
||||
r := new(randReader)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
privKeyAlice, pubKeyAlice, err := newhope.GenerateKeyPairAlice(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Alice, step 2: Send the public key to Bob
|
||||
fmt.Fprintf(c, "0x%x\n0x%x:0x%x\n", pubKeyAlice.Send,
|
||||
hc.cipheropts, hc.opts)
|
||||
|
||||
// [Bob does step 1-3], from which we read Bob's pubkey
|
||||
publicKeyBob := big.NewInt(0)
|
||||
fmt.Fscanf(c, "0x%x\n", publicKeyBob)
|
||||
var pubKeyBob newhope.PublicKeyBob
|
||||
for i := range(pubKeyBob.Send) {
|
||||
pubKeyBob.Send[i] = publicKeyBob.Bytes()[i]
|
||||
}
|
||||
log.Printf("[Got server pubKey[]:%v]\n", pubKeyBob)
|
||||
|
||||
// Read cipheropts, session opts
|
||||
_, err = fmt.Fscanf(c, "0x%x:0x%x\n",
|
||||
&hc.cipheropts, &hc.opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Alice, step 3: Derive shared secret
|
||||
// (NOTE: actual over-wire exchange was already done above. This is
|
||||
// the math voodoo 'exchange' done after receiving data from Bob.)
|
||||
aliceSharedSecret, err := newhope.KeyExchangeAlice(&pubKeyBob, privKeyAlice)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Printf("[Derived sharedSecret:0x%x]\n", aliceSharedSecret)
|
||||
hc.r, hc.rm, err = hc.getStream(aliceSharedSecret)
|
||||
hc.w, hc.wm, err = hc.getStream(aliceSharedSecret)
|
||||
return
|
||||
}
|
||||
|
||||
func NewHopeSimpleDialSetup(c io.ReadWriter, hc *Conn) (err error) {
|
||||
// Send hkexnet.Conn parameters to remote side
|
||||
|
||||
// Alice, step 1: Generate a key pair.
|
||||
r := new(randReader)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
privKeyAlice, pubKeyAlice, err := newhope.GenerateKeyPairSimpleAlice(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Alice, step 2: Send the public key to Bob
|
||||
fmt.Fprintf(c, "0x%x\n0x%x:0x%x\n", pubKeyAlice.Send,
|
||||
hc.cipheropts, hc.opts)
|
||||
|
||||
// [Bob does step 1-3], from which we read Bob's pubkey
|
||||
publicKeyBob := big.NewInt(0)
|
||||
fmt.Fscanf(c, "0x%x\n", publicKeyBob)
|
||||
var pubKeyBob newhope.PublicKeySimpleBob
|
||||
for i := range(pubKeyBob.Send) {
|
||||
pubKeyBob.Send[i] = publicKeyBob.Bytes()[i]
|
||||
}
|
||||
log.Printf("[Got server pubKey[]:%v]\n", pubKeyBob)
|
||||
|
||||
// Read cipheropts, session opts
|
||||
_, err = fmt.Fscanf(c, "0x%x:0x%x\n",
|
||||
&hc.cipheropts, &hc.opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Alice, step 3: Derive shared secret
|
||||
// (NOTE: actual over-wire exchange was already done above. This is
|
||||
// the math voodoo 'exchange' done after receiving data from Bob.)
|
||||
aliceSharedSecret, err := newhope.KeyExchangeSimpleAlice(&pubKeyBob, privKeyAlice)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Printf("[Derived sharedSecret:0x%x]\n", aliceSharedSecret)
|
||||
hc.r, hc.rm, err = hc.getStream(aliceSharedSecret)
|
||||
hc.w, hc.wm, err = hc.getStream(aliceSharedSecret)
|
||||
return
|
||||
}
|
||||
|
||||
func KyberDialSetup(c io.ReadWriter /*net.Conn*/, hc *Conn) (err error) {
|
||||
// Send hkexnet.Conn parameters to remote side
|
||||
|
||||
// Alice, step 1: Generate a key pair.
|
||||
r := new(randReader)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
var alicePublicKey *kyber.PublicKey
|
||||
var alicePrivateKey *kyber.PrivateKey
|
||||
switch hc.kex {
|
||||
|
@ -312,12 +413,12 @@ func KyberDialSetup(c io.ReadWriter /*net.Conn*/, hc *Conn) (err error) {
|
|||
hc.cipheropts, hc.opts)
|
||||
|
||||
// [Bob, step 1-3], from which we read cipher text
|
||||
cipherB := make([]byte, 4096)
|
||||
fmt.Fscanf(c, "0x%x\n", &cipherB)
|
||||
pubKeyB := make([]byte, 4096)
|
||||
fmt.Fscanf(c, "0x%x\n", &pubKeyB)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
log.Printf("[Got server ciphertext[]:%v]\n", cipherB)
|
||||
log.Printf("[Got server pubKeyB[]:%v]\n", pubKeyB)
|
||||
|
||||
// Read cipheropts, session opts
|
||||
_, err = fmt.Fscanf(c, "0x%x:0x%x\n",
|
||||
|
@ -327,7 +428,7 @@ func KyberDialSetup(c io.ReadWriter /*net.Conn*/, hc *Conn) (err error) {
|
|||
}
|
||||
|
||||
// Alice, step 3: Decrypt the KEM cipher text.
|
||||
aliceSharedSecret := alicePrivateKey.KEMDecrypt(cipherB)
|
||||
aliceSharedSecret := alicePrivateKey.KEMDecrypt(pubKeyB)
|
||||
|
||||
log.Printf("[Derived sharedSecret:0x%x]\n", aliceSharedSecret)
|
||||
hc.r, hc.rm, err = hc.getStream(aliceSharedSecret)
|
||||
|
@ -378,6 +479,84 @@ func HKExDialSetup(c io.ReadWriter /*net.Conn*/, hc *Conn) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func NewHopeAcceptSetup(c *net.Conn, hc *Conn) (err error) {
|
||||
r := new(randReader)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
// Bob, step 1: Deserialize Alice's public key from the binary encoding.
|
||||
alicePublicKey := big.NewInt(0)
|
||||
_, err = fmt.Fscanln(*c, alicePublicKey)
|
||||
log.Printf("[Got client pubKey:0x%x\n]", alicePublicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var pubKeyAlice newhope.PublicKeyAlice
|
||||
for i := range(pubKeyAlice.Send) {
|
||||
pubKeyAlice.Send[i] = alicePublicKey.Bytes()[i]
|
||||
}
|
||||
|
||||
_, err = fmt.Fscanf(*c, "0x%x:0x%x\n",
|
||||
&hc.cipheropts, &hc.opts)
|
||||
log.Printf("[Got cipheropts, opts:%v, %v]", hc.cipheropts, hc.opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Bob, step 2: Generate the KEM cipher text and shared secret.
|
||||
pubKeyBob, bobSharedSecret, err := newhope.KeyExchangeBob(r, &pubKeyAlice)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Bob, step 3: Send the cipher text to Alice.
|
||||
fmt.Fprintf(*c, "0x%x\n0x%x:0x%x\n", pubKeyBob.Send,
|
||||
hc.cipheropts, hc.opts)
|
||||
|
||||
log.Printf("[Derived sharedSecret:0x%x]\n", bobSharedSecret)
|
||||
hc.r, hc.rm, err = hc.getStream(bobSharedSecret)
|
||||
hc.w, hc.wm, err = hc.getStream(bobSharedSecret)
|
||||
return
|
||||
}
|
||||
|
||||
func NewHopeSimpleAcceptSetup(c *net.Conn, hc *Conn) (err error) {
|
||||
r := new(randReader)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
// Bob, step 1: Deserialize Alice's public key from the binary encoding.
|
||||
alicePublicKey := big.NewInt(0)
|
||||
_, err = fmt.Fscanln(*c, alicePublicKey)
|
||||
log.Printf("[Got client pubKey:0x%x\n]", alicePublicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var pubKeyAlice newhope.PublicKeySimpleAlice
|
||||
for i := range(pubKeyAlice.Send) {
|
||||
pubKeyAlice.Send[i] = alicePublicKey.Bytes()[i]
|
||||
}
|
||||
|
||||
_, err = fmt.Fscanf(*c, "0x%x:0x%x\n",
|
||||
&hc.cipheropts, &hc.opts)
|
||||
log.Printf("[Got cipheropts, opts:%v, %v]", hc.cipheropts, hc.opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Bob, step 2: Generate the KEM cipher text and shared secret.
|
||||
pubKeyBob, bobSharedSecret, err := newhope.KeyExchangeSimpleBob(r, &pubKeyAlice)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Bob, step 3: Send the cipher text to Alice.
|
||||
fmt.Fprintf(*c, "0x%x\n0x%x:0x%x\n", pubKeyBob.Send,
|
||||
hc.cipheropts, hc.opts)
|
||||
|
||||
log.Printf("[Derived sharedSecret:0x%x]\n", bobSharedSecret)
|
||||
hc.r, hc.rm, err = hc.getStream(bobSharedSecret)
|
||||
hc.w, hc.wm, err = hc.getStream(bobSharedSecret)
|
||||
return
|
||||
}
|
||||
|
||||
func KyberAcceptSetup(c *net.Conn, hc *Conn) (err error) {
|
||||
// Bob, step 1: Deserialize Alice's public key from the binary encoding.
|
||||
alicePublicKey := big.NewInt(0)
|
||||
|
@ -411,13 +590,13 @@ func KyberAcceptSetup(c *net.Conn, hc *Conn) (err error) {
|
|||
|
||||
// Bob, step 2: Generate the KEM cipher text and shared secret.
|
||||
r := new(randReader)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
cipherText, bobSharedSecret, err := peerPublicKey.KEMEncrypt(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Bob, step 3: Send the cipher text to Alice.
|
||||
//fmt.Println("cipherText:",cipherText)
|
||||
fmt.Fprintf(*c, "0x%x\n0x%x:0x%x\n", cipherText,
|
||||
hc.cipheropts, hc.opts)
|
||||
|
||||
|
@ -525,6 +704,16 @@ func Dial(protocol string, ipport string, extensions ...string) (hc Conn, err er
|
|||
if KyberDialSetup(c, &hc) != nil {
|
||||
return Conn{}, nil
|
||||
}
|
||||
case KEX_NEWHOPE:
|
||||
log.Printf("[Setting up for KEX_NEWHOPE %d]\n", hc.kex)
|
||||
if NewHopeDialSetup(c, &hc) != nil {
|
||||
return Conn{}, nil
|
||||
}
|
||||
case KEX_NEWHOPE_SIMPLE:
|
||||
log.Printf("[Setting up for KEX_NEWHOPE_SIMPLE %d]\n", hc.kex)
|
||||
if NewHopeSimpleDialSetup(c, &hc) != nil {
|
||||
return Conn{}, nil
|
||||
}
|
||||
default:
|
||||
return Conn{}, err
|
||||
}
|
||||
|
@ -686,6 +875,16 @@ func (hl *HKExListener) Accept() (hc Conn, err error) {
|
|||
if KyberAcceptSetup(&c, &hc) != nil {
|
||||
return Conn{}, err
|
||||
}
|
||||
case KEX_NEWHOPE:
|
||||
log.Printf("[Setting up for KEX_NEWHOPE %d]\n", hc.kex)
|
||||
if NewHopeAcceptSetup(&c, &hc) != nil {
|
||||
return Conn{}, err
|
||||
}
|
||||
case KEX_NEWHOPE_SIMPLE:
|
||||
log.Printf("[Setting up for KEX_NEWHOPE_SIMPLE %d]\n", hc.kex)
|
||||
if NewHopeSimpleAcceptSetup(&c, &hc) != nil {
|
||||
return Conn{}, err
|
||||
}
|
||||
default:
|
||||
return Conn{}, err
|
||||
}
|
||||
|
|
|
@ -623,11 +623,11 @@ func main() {
|
|||
flag.BoolVar(&vopt, "v", false, "show version")
|
||||
flag.BoolVar(&dbg, "d", false, "debug logging")
|
||||
flag.StringVar(&cipherAlg, "c", "C_AES_256", "`cipher` [\"C_AES_256\" | \"C_TWOFISH_128\" | \"C_BLOWFISH_64\" | \"C_CRYPTMT1\"]")
|
||||
flag.StringVar(&hmacAlg, "m", "H_SHA256", "`hmac` [\"H_SHA256\"]")
|
||||
flag.StringVar(&kexAlg, "k", "KEX_HERRADURA256", "`kex` [\"KEX_HERRADURA{256/512/1024/2048}\" | \"KEX_KYBER{512/768/1024}\"]")
|
||||
flag.StringVar(&hmacAlg, "m", "H_SHA256", "`hmac` [\"H_SHA256\" | \"H_SHA512\"]")
|
||||
flag.StringVar(&kexAlg, "k", "KEX_HERRADURA256", "`kex` [\"KEX_HERRADURA{256/512/1024/2048}\" | \"KEX_KYBER{512/768/1024}\" | \"KEX_NEWHOPE\" | \"KEX_NEWHOPE_SIMPLE\"]")
|
||||
flag.UintVar(&port, "p", 2000, "`port`")
|
||||
//flag.StringVar(&authCookie, "a", "", "auth cookie")
|
||||
flag.BoolVar(&chaffEnabled, "e", true, "enabled chaff pkts (default true)")
|
||||
flag.BoolVar(&chaffEnabled, "e", true, "enable chaff pkts")
|
||||
flag.UintVar(&chaffFreqMin, "f", 100, "`msecs-min` chaff pkt freq min (msecs)")
|
||||
flag.UintVar(&chaffFreqMax, "F", 5000, "`msecs-max` chaff pkt freq max (msecs)")
|
||||
flag.UintVar(&chaffBytesMax, "B", 64, "chaff pkt size max (bytes)")
|
||||
|
|
|
@ -387,7 +387,7 @@ func main() {
|
|||
|
||||
flag.BoolVar(&vopt, "v", false, "show version")
|
||||
flag.StringVar(&laddr, "l", ":2000", "interface[:port] to listen")
|
||||
flag.BoolVar(&chaffEnabled, "e", true, "enabled chaff pkts")
|
||||
flag.BoolVar(&chaffEnabled, "e", true, "enable chaff pkts")
|
||||
flag.UintVar(&chaffFreqMin, "f", 100, "chaff pkt freq min (msecs)")
|
||||
flag.UintVar(&chaffFreqMax, "F", 5000, "chaff pkt freq max (msecs)")
|
||||
flag.UintVar(&chaffBytesMax, "B", 64, "chaff pkt size max (bytes)")
|
||||
|
|
Loading…
Reference in a new issue