aucpace

package module
v0.0.0-...-419a316 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 25, 2020 License: BSD-3-Clause Imports: 0 Imported by: 0

Documentation

Overview

Package aucpace provides easy to use (strong) AuCPace operations.

Example
package main

import (
	"bytes"
	"fmt"
	"os"

	Client "github.com/bytemare/pake/AuCPace/client"
	Server "github.com/bytemare/pake/AuCPace/server"
	"github.com/bytemare/pake/AuCPace/verifier"
	"github.com/bytemare/pake/crypto"
	"github.com/bytemare/pake/crypto/hashing/phf/argon2id"
)

var serverID = []byte("server")
var ad []byte = nil
var username = []byte("user")
var password = []byte("password")

const ihfKeylen = 64
const ssidLength = 16

func newPasswordVerifierSetup() *verifier.PasswordVerifierRecord {
	/**
	  Database requirements :
	  	- if there's a connection attempt for a user that is not known, the database should still return an entry,
	  		but with q = hash(username || seed) and W = map_to_group(w), and the front end should use rate-limiting.
	  		Both prevent against user enumeration.
	*/
	/*
		We want to set up a new password for a client that already exists and has authenticated.
		We dig up the pvr from database given the username, and set q := random scalar, and W = nil.
	*/
	pvr := verifier.PvrInit(verifier.SAPVD, argon2id.NewArgon2idSigma(ihfKeylen), username)
	if err := pvr.Buildq(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	q := pvr.SaltDerivationQ()

	sigma, err := pvr.Sigma.Encode()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	/*
		The server sends encoded sigma and q to the client.
	*/

	client := Client.New(username, password, serverID, nil, ad, crypto.Ristretto255sha512)

	// The client builds the verifier W from username, password, a q derivation and sigma
	W, err := client.BuildVerifier(q, sigma)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	/*
		Client sends W to server, and server completes password verifier record
	*/

	pvr.Finish(W)

	return pvr
}

func main() {
	/*
		Before the authentication session, a client must have created an account within the server, that holds a PVR
		for the client. For the demo, we'll set one p.
	*/
	pvr := newPasswordVerifierSetup()

	/*
		Start AuCPace protocol

		Step 1 : OPRF Blind Salt exchange
	*/
	ssid, err := crypto.RandomBytes(ssidLength)
	if err != nil {
		fmt.Println(err)
		return
	}

	client := Client.New(username, password, serverID, ssid, ad, crypto.Ristretto255sha512)

	// Client calculates a blinder U for the salt
	U, err := client.Start()
	if err != nil {
		fmt.Println(err)
		return
	}

	/*
		Client sends ssid, U and username to server
	*/

	// Server receives username and U, and eventually ssid
	// Server looks up database to retrieve Password Verifier Record pvr

	server := Server.New(serverID, username, pvr, ssid, ad, crypto.Ristretto255sha512)

	/*
		Step 2 : calculate UQ,X,sigma and Ya

		Begin CPace sub step
	*/

	UQ, X, sigma, Ya, err := server.Start(U)
	if err != nil {
		fmt.Println(err)
		return
	}

	/*
		Server sends (UQ,X,sigma,Ya) and pvr type to client

		Upon reception, the client :
			- unblinds the salt if necessary
			- computes XWs, the password to be used in the CPace sub steps
			- compute Yb
			- Derive ISK
			- if an error is detected at these stages, abort
			- if not, send Yb to server
	*/

	Yb, Tb, err := client.Continue(pvr.PvrType, UQ, X, sigma, Ya)
	if err != nil {
		fmt.Println(err)
		return
	}

	/*
		Client sends Yb to server to complete the CPace sub steps,
		The Client also sends Tb, its authentication tag
	*/

	// Server receives Yb from Client, and calculates the intermediate Shared Secret Session Key
	// At this point both parties have the same Intermediary Secret Session Key

	/*
		CPace sub steps completed and validated

		Step 3 : Start explicit authentication
	*/

	// Server calculates its own authentication tags

	// If the received authentication tag Tb did not match
	// the verification value Tb_v A MUST abort.

	// If the tag is validated, send Ta to client
	// Server MUST abort if Tb != Tb_v
	if err := server.Continue(Yb, Tb); err != nil {
		fmt.Println(err)
		return
	}

	Ta := server.AuthenticationTag()

	/*
		Server sends authentication tag Ta to client
	*/

	// Client receives T_a from server and compare this to the verification value Ta_v.
	// Client MUST abort if Ta != Ta_v
	if err := client.VerifyPeerTag(Ta); err != nil {
		fmt.Println(err)
		return
	}

	/*
		End of Explicit Authentication Step

		Both parties are now mutually authenticated and can derive the AuCPace shared secret session key
	*/

	serverSK := server.Finish()
	clientSK := client.Finish()

	/*
		Both keys are identical if and only if :
			- ssid and ci are the same for both parties
			- the password verifier in the server database for the user
			  was calculated form the cleartext password used by the user
	*/

	if bytes.Equal(clientSK, serverSK) {
		println("Success ! Both parties share the same secret session key !")
	} else {
		println("Failed. Client and server keys are different.")
	}
	// Output : Success ! Both parties share the same secret session key !
}
Output:

Directories

Path Synopsis
Package client provides an implementation of a (strong) AuCPace client.
Package client provides an implementation of a (strong) AuCPace client.
Package server provides an implementation for a (strong) AuCPace server.
Package server provides an implementation for a (strong) AuCPace server.
Package verifier implements an AuCPace Password Verifier Record as per the AuCPace draft
Package verifier implements an AuCPace Password Verifier Record as per the AuCPace draft

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL