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
							
								
									c12e3bca9e
								
							
						
					
					
						commit
						9c0f01fb4f
					
				
					 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue