opaque

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Jan 11, 2023 License: BSD-3-Clause Imports: 9 Imported by: 0

Documentation

Overview

Package opaque implements OPAQUE, an asymmetric password-authenticated key exchange protocol that is secure against pre-computation attacks. It enables a client to authenticate to a server without ever revealing its password to the server. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html

Example (Registration)
package main

import (
	"bytes"
	"fmt"
	"log"

	"github.com/cymony/cryptomony/opaque"
)

func logFatalln(err error) {
	if err != nil {
		log.Fatalln(err)
	}
}

func main() {
	// Must be initialize server on the server side.
	// Server's private and public keys should not be changed on every run.
	// Oprf seed must be client specific. So the application should have oprf seed per client.
	serverConf := opaque.ServerConfiguration{
		ServerID:         []byte("example.com"),    // Server Identifier. Must be same on client
		ServerPrivateKey: nil,                      // If private key is nil, generates a new key automatically
		OpaqueSuite:      opaque.Ristretto255Suite, // Suite with recommended setup. Must be same on client
	}

	server, err := opaque.NewServer(&serverConf)
	logFatalln(err)

	// Must be initialized client on the client side.
	clientConf := opaque.ClientConfiguration{
		ServerID:    []byte("example.com"),    // Server Identifier. Must be same on server
		OpaqueSuite: opaque.Ristretto255Suite, // Suite with recommended setup. Must be same on server
	}

	client := opaque.NewClient(&clientConf)

	// chosenUserID is the email address for registration
	chosenUserID := []byte("anemail@domain.com")
	// chosenPassword is the password for registration
	chosenPassword := []byte("SuperSecretPass")

	// The client creates Registration Request with chosen password
	// regReq looks like this;
	// {
	// 	"BlindedMessage": "Encoded Blinded Password"
	// }
	// Client must be store blind and should not send to server.
	// Only regReq should be sent to the server
	clRegState, regReq, err := client.CreateRegistrationRequest(chosenPassword)
	logFatalln(err)
	encodedRegReq, err := regReq.Encode()
	logFatalln(err)

	// Then server received the Registration Request. Now it will generate Registration Response.
	// In this step, server generates credential identifier and oprf seed. It must be unique among clients of the server.
	// regRes looks like this;
	// {
	// 	"EvaluatedMessage": "Encoded Evaluted Message",
	// 	"ServerPublicKey": "Encoded Server Public Key"
	// }

	// Server must generate Nh size Oprf seed per client. And must be stored it only for that client.
	// To generate Nh size Oprf seed you can use GenerateOprfSeed function safely.
	oprfSeed := server.GenerateOprfSeed()
	credentialIdentifier := []byte("can_be_database_identifier_must_be_uniq_per_client")

	regRes, err := server.CreateRegistrationResponse(encodedRegReq, credentialIdentifier, oprfSeed)
	logFatalln(err)
	encodedRegRes, err := regRes.Encode()
	logFatalln(err)

	// Then client receives the regRes. Now it will generate record to be stored on server side.
	// If client identity is nil, the client public key will be used automatically. Usually, email address is used as client identity.
	// Only regRecord should send to the server.
	regRecord, regExportKey, err := client.FinalizeRegistrationRequest(clRegState, chosenUserID, encodedRegRes)
	logFatalln(err)
	// Registration Finished !!

	// Login Start
	// Firstly, Client executes ClientInit function with the password to generate KE1 Message.
	// Client should send only ke1 message to the server.
	clLoginState, ke1Message, err := client.ClientInit(chosenPassword)
	logFatalln(err)
	encodedKE1Message, err := ke1Message.Encode()
	logFatalln(err)

	// Server already know record, credential identifier, chosen user id and oprf seed generated on registration.
	encodedRecord, err := regRecord.Encode()
	logFatalln(err)

	// Now server executes ServerInit function with ke1 message. And generates KE2 Message.
	// Server should send only ke2 message to the client.
	svLoginState, ke2Message, err := server.ServerInit(encodedRecord, encodedKE1Message, credentialIdentifier, chosenUserID, oprfSeed)
	logFatalln(err)
	encodedKE2Message, err := ke2Message.Encode()
	logFatalln(err)

	// Than, client executes ClientFinish function to generate KE3 Message and to collect export key.
	ke3Message, clSessionKey, lgnExportKey, err := client.ClientFinish(clLoginState, chosenUserID, encodedKE2Message)
	logFatalln(err)
	encodedKE3Message, err := ke3Message.Encode()
	logFatalln(err)

	// Finally, server executes ServerFinish. If this function is not returns an error, than you can authenticate the client.
	svSessionKey, err := server.ServerFinish(svLoginState, encodedKE3Message)
	logFatalln(err)

	log.Println("ClientSessionKey: ", clSessionKey)
	log.Println("ServerSessionKey: ", svSessionKey)
	log.Println("Registration Export Key: ", regExportKey)
	log.Println("Login Export Key: ", lgnExportKey)

	if !bytes.Equal(clSessionKey, svSessionKey) {
		log.Fatalln("Collected session keys are different !!")
	}

	if !bytes.Equal(regExportKey, lgnExportKey) {
		log.Fatalln("Collected export keys are different !!")
	}

	fmt.Println("OPAQUE registration and login")
}
Output:

OPAQUE registration and login

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrEnvelopeRecovery         = errors.New("opaque: envelope recovery failed")
	ErrSeedLength               = errors.New("opaque: unexpected seed length")
	ErrPrivateKeyInitialization = errors.New("opaque: private key not initialized")
	ErrPublicKeyInitialization  = errors.New("opaque: public key not initialized")
	ErrRecoverCredentialsFailed = errors.New("opaque: recover credentials operation failed")
	ErrOPRFBlind                = errors.New("opaque: oprf blind operation failed")
	ErrOPRFFinalize             = errors.New("opaque: oprf finalize operation failed")
	ErrOPRFEvaluate             = errors.New("opaque: oprf evaluate operation failed")
	ErrOPRFSeedLength           = errors.New("opaque: unexpected length of oprf seed")
	ErrServerAuthentication     = errors.New("opaque: server authentication failed")
	ErrClientAuthentication     = errors.New("opaque: client authentication failed")
	ErrDecodingFailed           = errors.New("opaque: decoding failed")
	ErrEncodingFailed           = errors.New("opaque: encoding failed")
	ErrDeserializationFailed    = errors.New("opaque: deserialization failed")
	ErrSerializationFailed      = errors.New("opaque: serialization failed")
)

Functions

This section is empty.

Types

type AuthRequest

type AuthRequest struct {
	ClientKeyshare *PublicKey // client_keyshare[Npk]
	ClientNonce    []byte     // client_nonce[Nn]
}

AuthRequest represents the AuthRequest struct on the draft. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-ake-messages

func (*AuthRequest) Decode

func (ar *AuthRequest) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the AuthRequest struct.

func (*AuthRequest) Deserialize

func (ar *AuthRequest) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the AuthRequest struct

func (*AuthRequest) Encode

func (ar *AuthRequest) Encode() ([]byte, error)

Encode serializes the AuthRequest into bytes but with 2 byte length descriptors.

func (*AuthRequest) Serialize

func (ar *AuthRequest) Serialize() ([]byte, error)

Serialize serializes the AuthRequest to bytes

type AuthResponse

type AuthResponse struct {
	ServerNonce    []byte     // server_nonce[Nn]
	ServerKeyshare *PublicKey // server_keyshare[Npk]
	ServerMAC      []byte     // server_mac[Nm]
}

AuthResponse represents the AuthResponse struct on the draft. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-ake-messages

func (*AuthResponse) Decode

func (ar *AuthResponse) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the AuthResponse struct.

func (*AuthResponse) Deserialize

func (ar *AuthResponse) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the AuthResponse struct

func (*AuthResponse) Encode

func (ar *AuthResponse) Encode() ([]byte, error)

Encode serializes the AuthResponse into bytes but with 2 byte length descriptors.

func (*AuthResponse) Serialize

func (ar *AuthResponse) Serialize() ([]byte, error)

Serialize serializes the AuthResponse to bytes

type CleartextCredentials

type CleartextCredentials struct {
	ServerPublicKey []byte
	ServerIdentity  []byte
	ClientIdentity  []byte
}

CleartextCredentials represents the CleartextCredentials struct on the draft. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-client-credential-storage-a

func CreateCleartextCredentials

func CreateCleartextCredentials(sPubKey, cPubKey, serverIdentity, clientIdentity []byte) *CleartextCredentials

CreateCleartextCredentials implements the CreateCleartextCredentials function on the draft. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-client-credential-storage-a

func (*CleartextCredentials) Decode

func (cc *CleartextCredentials) Decode(suite Suite, data []byte) error

Decode decodes given data into the struct. Given data must be output of Encode function

func (*CleartextCredentials) Encode

func (cc *CleartextCredentials) Encode() ([]byte, error)

Encode encodes server public key, server identity and client identity to byte array. To Decode, use the Decode function only

type Client

type Client interface {
	// CreateRegistrationRequest computes blinded message and returns (RegistrationRequest, blind).
	// Returned blind is client private value to be use in FinalizeRegistrationRequest and it must not send to server.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-createregistrationrequest
	CreateRegistrationRequest(password []byte) (clRegState *ClientRegistrationState, regReq *RegistrationRequest, err error)
	// FinalizeRegistrationRequest generates RegistrationRecord to store on server side.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-finalizeregistrationrequest
	FinalizeRegistrationRequest(clRegState *ClientRegistrationState, clientIdentity, regRes []byte) (regRec *RegistrationRecord, exportKey []byte, err error)
	// ClientInit function begins the AKE protocol and produces the client's KE1 output for the server.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-clientinit
	ClientInit(password []byte) (clLoginState *ClientLoginState, ke1Message *KE1, err error)
	// The ClientFinish function completes the AKE protocol for the client and produces the client's KE3 output for the server, as well as the session_key and export_key outputs from the AKE.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-clientfinish
	ClientFinish(clLoginState *ClientLoginState, clientIdentity []byte, ke2 []byte) (ke3Message *KE3, sessionKey []byte, exportKey []byte, err error)
}

Client interface represents the client instance.

func NewClient

func NewClient(conf *ClientConfiguration) Client

NewClient initializes the client instance according to configuration

type ClientConfiguration

type ClientConfiguration struct {
	ServerID    []byte     // Server Identity. Usually, domain name
	OpaqueSuite Identifier // Chosen Opaque Suite
}

ClientConfiguration contains configurations to initialize client instance

type ClientLoginState

type ClientLoginState struct {
	Blind        *eccgroup.Scalar
	ClientSecret *PrivateKey
	KE1          *KE1
	Password     []byte
}

ClientLoginState represents the client's ake state to give ClientFinish function as parameter. This library does not manage the state internally.

func (*ClientLoginState) Decode added in v0.0.2

func (cls *ClientLoginState) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the ClientLoginState struct.

func (*ClientLoginState) Deserialize added in v0.0.2

func (cls *ClientLoginState) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the ClientLoginState struct

func (*ClientLoginState) Encode added in v0.0.2

func (cls *ClientLoginState) Encode() ([]byte, error)

Encode serializes the ClientLoginState into bytes but with 2 byte length descriptors.

func (*ClientLoginState) Serialize added in v0.0.2

func (cls *ClientLoginState) Serialize() ([]byte, error)

Serialize serializes the ClientLoginState to bytes

type ClientRegistrationState

type ClientRegistrationState struct {
	Blind    *eccgroup.Scalar
	Password []byte
}

ClientRegistrationState represents the client's registration state to give FinalizeRegistrationRequest function as parameter. This library does not manage the state internally.

func (*ClientRegistrationState) Decode added in v0.0.2

func (crs *ClientRegistrationState) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the ClientRegistrationState struct.

func (*ClientRegistrationState) Deserialize added in v0.0.2

func (crs *ClientRegistrationState) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the ClientRegistrationState struct

func (*ClientRegistrationState) Encode added in v0.0.2

func (crs *ClientRegistrationState) Encode() ([]byte, error)

Encode serializes the ClientRegistrationState into bytes but with 2 byte length descriptors.

func (*ClientRegistrationState) Serialize added in v0.0.2

func (crs *ClientRegistrationState) Serialize() ([]byte, error)

Serialize serializes the ClientRegistrationState to bytes

type CredentialRequest

type CredentialRequest struct {
	BlindedMessage *eccgroup.Element // blinded_message[Noe]
}

CredentialRequest represents the CredentialRequest struct on the draft. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-credential-retrieval-messag

func (*CredentialRequest) Decode

func (cr *CredentialRequest) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the CredentialRequest struct.

func (*CredentialRequest) Deserialize

func (cr *CredentialRequest) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the CredentialRequest struct

func (*CredentialRequest) Encode

func (cr *CredentialRequest) Encode() ([]byte, error)

Encode serializes the CredentialRequest into bytes but with 2 byte length descriptors.

func (*CredentialRequest) Serialize

func (cr *CredentialRequest) Serialize() ([]byte, error)

Serialize serializes the CredentialRequest to bytes

type CredentialResponse

type CredentialResponse struct {
	EvaluatedMessage *eccgroup.Element // evaluated_message[Noe]
	MaskingNonce     []byte            // masking_nonce[Nn]
	MaskedResponse   []byte            // masked_response[Npk + Ne]
}

CredentialResponse represents the CredentialResponse struct on the draft. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-credential-retrieval-messag

func (*CredentialResponse) Decode

func (cr *CredentialResponse) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the CredentialResponse struct.

func (*CredentialResponse) Deserialize

func (cr *CredentialResponse) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the CredentialResponse struct

func (*CredentialResponse) Encode

func (cr *CredentialResponse) Encode() ([]byte, error)

Encode serializes the CredentialResponse into bytes but with 2 byte length descriptors.

func (*CredentialResponse) Serialize

func (cr *CredentialResponse) Serialize() ([]byte, error)

Serialize serializes the CredentialResponse to bytes

type Envelope

type Envelope struct {
	Nonce   []byte // nonce[Nn]
	AuthTag []byte // auth_tag[Nm]
}

Envelope represents the envelope struct on the draft. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-envelope-structure

func (*Envelope) Decode

func (e *Envelope) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the Envelope struct.

func (*Envelope) Deserialize

func (e *Envelope) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the Envelope struct

func (*Envelope) Encode

func (e *Envelope) Encode() ([]byte, error)

Encode serializes the Envelope into bytes but with 2 byte length descriptors.

func (*Envelope) Serialize

func (e *Envelope) Serialize() ([]byte, error)

Serialize serializes the Envelope to bytes

type Identifier

type Identifier uint

Identifier is the type constant for supported suites

const (
	// Ristretto255Suite is the identifier for recommended opaque suite -> OPRF(ristretto255, SHA-512), HKDF-SHA-512, HMAC-SHA-512, SHA-512, Scrypt(32768,8,1), internal, ristretto255
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-configurations
	Ristretto255Suite Identifier = 1 + iota
	// P256Suite is the identifier for recommended opaque suite -> OPRF(P-256, SHA-256), HKDF-SHA-256, HMAC-SHA-256, SHA-256, Scrypt(32768,8,1), internal, P-256
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-configurations
	P256Suite
)

func (Identifier) New

func (i Identifier) New() Suite

New initialize new suite instance and returns it.

type KE1

type KE1 struct {
	CredentialRequest *CredentialRequest // credential_request[Noe]
	AuthRequest       *AuthRequest       // auth_request[Nn+Npk]
}

KE1 represents the first message sent from client to server on login. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-ake-messages

func (*KE1) Decode

func (ke *KE1) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the KE1 struct.

func (*KE1) Deserialize

func (ke *KE1) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the KE1 struct

func (*KE1) Encode

func (ke *KE1) Encode() ([]byte, error)

Encode serializes the KE1 into bytes but with 2 byte length descriptors.

func (*KE1) Serialize

func (ke *KE1) Serialize() ([]byte, error)

Serialize serializes the KE1 to bytes

type KE2

type KE2 struct {
	CredentialResponse *CredentialResponse // credential_response[Noe+Nn+Npk+Ne]
	AuthResponse       *AuthResponse       // auth_response[Nn+Npk+Nm]
}

KE2 represents the second message sent from server to client on login. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-ake-messages

func (*KE2) Decode

func (ke *KE2) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the KE2 struct.

func (*KE2) Deserialize

func (ke *KE2) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the KE2 struct

func (*KE2) Encode

func (ke *KE2) Encode() ([]byte, error)

Encode serializes the KE2 into bytes but with 2 byte length descriptors.

func (*KE2) Serialize

func (ke *KE2) Serialize() ([]byte, error)

Serialize serializes the KE2 to bytes

type KE3

type KE3 struct {
	ClientMAC []byte // client_mac[Nm]
}

KE3 represents the third message sent from client to server on login. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-ake-messages

func (*KE3) Decode

func (ke *KE3) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the KE3 struct.

func (*KE3) Deserialize

func (ke *KE3) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the KE3 struct

func (*KE3) Encode

func (ke *KE3) Encode() ([]byte, error)

Encode serializes the KE3 into bytes but with 2 byte length descriptors.

func (*KE3) Serialize

func (ke *KE3) Serialize() ([]byte, error)

Serialize serializes the KE3 to bytes

type PrivateKey

type PrivateKey struct {
	// contains filtered or unexported fields
}

PrivateKey identify the private key according to group

func (*PrivateKey) MarshalBinary

func (pk *PrivateKey) MarshalBinary() ([]byte, error)

MarshalBinary marshals the private key to bytes

func (*PrivateKey) MarshalText

func (pk *PrivateKey) MarshalText() ([]byte, error)

MarshalText marshals the private key to base64 encoded bytes

func (*PrivateKey) Public

func (pk *PrivateKey) Public() *PublicKey

Public returns corresponding public key

func (*PrivateKey) UnmarshalBinary

func (pk *PrivateKey) UnmarshalBinary(s Suite, data []byte) error

UnmarshalBinary unmarshals given data to PrivateKey struct according to given suite

func (*PrivateKey) UnmarshalText

func (pk *PrivateKey) UnmarshalText(s Suite, text []byte) error

UnmarshalText unmarshals given data to PrivateKey struct according to given suite

type PublicKey

type PublicKey struct {
	// contains filtered or unexported fields
}

PublicKey identify the public key according to group

func (*PublicKey) MarshalBinary

func (pk *PublicKey) MarshalBinary() ([]byte, error)

MarshalBinary marshals the public key to bytes

func (*PublicKey) MarshalText

func (pk *PublicKey) MarshalText() ([]byte, error)

MarshalText marshals the public key to base64 encoded bytes

func (*PublicKey) UnmarshalBinary

func (pk *PublicKey) UnmarshalBinary(s Suite, data []byte) error

UnmarshalBinary unmarshals given data to PublicKey struct according to given suite

func (*PublicKey) UnmarshalText

func (pk *PublicKey) UnmarshalText(s Suite, text []byte) error

UnmarshalText unmarshals given data to PublicKey struct according to given suite

type RegistrationRecord

type RegistrationRecord struct {
	Envelope     *Envelope  // envelope[Ne]
	ClientPubKey *PublicKey // client_public_key[Npk]
	MaskingKey   []byte     // masking_key[Nh]

}

RegistrationRecord represents the third message sent from client to server on registration. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-registration-messages

func (*RegistrationRecord) Decode

func (rr *RegistrationRecord) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the RegistrationRecord struct.

func (*RegistrationRecord) Deserialize

func (rr *RegistrationRecord) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the RegistrationRecord struct

func (*RegistrationRecord) Encode

func (rr *RegistrationRecord) Encode() ([]byte, error)

Encode serializes the RegistrationRecord into bytes but with 2 byte length descriptors.

func (*RegistrationRecord) Serialize

func (rr *RegistrationRecord) Serialize() ([]byte, error)

Serialize serializes the RegistrationRecord to bytes

type RegistrationRequest

type RegistrationRequest struct {
	BlindedMessage *eccgroup.Element // blinded_message[Noe]
}

RegistrationRequest represents the first message sent from client to server on registration. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-registration-messages

func (*RegistrationRequest) Decode

func (rr *RegistrationRequest) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the RegistrationRequest struct.

func (*RegistrationRequest) Deserialize

func (rr *RegistrationRequest) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the RegistrationRequest struct

func (*RegistrationRequest) Encode

func (rr *RegistrationRequest) Encode() ([]byte, error)

Encode serializes the RegistrationRequest into bytes but with 2 byte length descriptors.

func (*RegistrationRequest) Serialize

func (rr *RegistrationRequest) Serialize() ([]byte, error)

Serialize serializes the RegistrationRequest to bytes

type RegistrationResponse

type RegistrationResponse struct {
	EvaluatedMessage *eccgroup.Element // evaluated_message[Noe]
	ServerPublicKey  *PublicKey        // server_public_key[Npk]
}

RegistrationResponse represents the second message sent from server to client on registration. Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-registration-messages

func (*RegistrationResponse) Decode

func (rr *RegistrationResponse) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the RegistrationResponse struct.

func (*RegistrationResponse) Deserialize

func (rr *RegistrationResponse) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the RegistrationResponse struct

func (*RegistrationResponse) Encode

func (rr *RegistrationResponse) Encode() ([]byte, error)

Encode serializes the RegistrationResponse into bytes but with 2 byte length descriptors.

func (*RegistrationResponse) Serialize

func (rr *RegistrationResponse) Serialize() ([]byte, error)

Serialize serializes the RegistrationResponse to bytes

type Server

type Server interface {
	// CreateRegistrationResponse evaluates the RegistrationRequest and returns RegistrationResponse
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-createregistrationresponse
	CreateRegistrationResponse(regReq []byte, credentialIdentifier, oprfSeed []byte) (*RegistrationResponse, error)
	// ServerInit function continues the AKE protocol by processing the client's KE1 message and producing the server's KE2 output.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-serverinit
	ServerInit(clRecord []byte, ke1Message []byte, credentialIdentifier []byte, clientIdentity []byte, oprfSeed []byte) (*ServerLoginState, *KE2, error)
	// The ServerFinish function completes the AKE protocol for the server, yielding the session_key.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-serverfinish
	ServerFinish(svLoginState *ServerLoginState, ke3Message []byte) ([]byte, error)
	// GenerateOprfSeed generates randomly secure oprf seed with suitable length
	GenerateOprfSeed() []byte
}

Server interface represents the server instance.

func NewServer

func NewServer(conf *ServerConfiguration) (Server, error)

NewServer initializes the server instance according to configuration

type ServerConfiguration

type ServerConfiguration struct {
	ServerID         []byte     // Server Identity. Usually, domain name
	ServerPrivateKey []byte     // Serialized server private key value
	OpaqueSuite      Identifier // Chosen Opaque Suite
}

ServerConfiguration contains configurations to initialize server instance

type ServerLoginState

type ServerLoginState struct {
	ExpectedClientMac []byte
	SessionKey        []byte
}

ServerLoginState represents the server's ake state to give ServerFinish function as parameter. This library does not manage the state internally.

func (*ServerLoginState) Decode added in v0.0.2

func (sls *ServerLoginState) Decode(suite Suite, data []byte) error

Decode deserializes encoded data into the ServerLoginState struct.

func (*ServerLoginState) Deserialize added in v0.0.2

func (sls *ServerLoginState) Deserialize(suite Suite, data []byte) error

Deserialize deserializes bytes into the ServerLoginState struct

func (*ServerLoginState) Encode added in v0.0.2

func (sls *ServerLoginState) Encode() ([]byte, error)

Encode serializes the ServerLoginState into bytes but with 2 byte length descriptors.

func (*ServerLoginState) Serialize added in v0.0.2

func (sls *ServerLoginState) Serialize() ([]byte, error)

Serialize serializes the ServerLoginState to bytes

type Suite

type Suite interface {
	// OPRF function returns the oprf suite used by opaque suite.
	OPRF() oprf.Suite
	// Group function returns the prime-order group used by opaque suite.
	Group() eccgroup.Group
	// Hash	function returns the hash interface used by opaque suite.
	Hash() hash.Hash
	// Expand function executes HKDF Expand according to opaque suite's hash algorithm.
	Expand(pseudorandomKey []byte, info []byte, length int) []byte
	// Extract function executes HKDF Extract according to opaque suite's hash algorithm.
	Extract(salt, secret []byte) []byte
	// MAC function executes Hmac according to opaque suite's hash algorithm.
	MAC(key, message []byte) ([]byte, error)
	// Stretch function performs key stretching according to opaque suite's ksf algorithm.
	Stretch(password []byte, length int) ([]byte, error)
	// Store implements opaque protocol's Envelope Creation step.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-envelope-creation.
	Store(randomizedPwd []byte, sPubKey *PublicKey, serverIdentity, clientIdentity []byte) (*Envelope, *PublicKey, []byte, []byte, error)
	// Recover implements opaque protocol's Envelope Recovery step.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-envelope-recovery.
	Recover(randomizedPwd []byte, sPubKey *PublicKey, envelope *Envelope, serverIdentity, clientIdentity []byte) (*PrivateKey, []byte, error)
	// GenerateOPRFSeed generates random Nh bytes to use as oprf seed.
	GenerateOprfSeed() []byte

	// Registration Functions
	//
	// CreateRegistrationRequest computes blinded message and returns (RegistrationRequest, blind).
	// Returned blind is client private value to be use in FinalizeRegistrationRequest and it must not send to server.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-createregistrationrequest
	CreateRegistrationRequest(password []byte) (*RegistrationRequest, *eccgroup.Scalar, error)
	// CreateRegistrationResponse evaluates the RegistrationRequest and returns RegistrationResponse
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-createregistrationresponse
	CreateRegistrationResponse(regReq *RegistrationRequest, serverPubKey *PublicKey, credentialIdentifier, oprfSeed []byte) (*RegistrationResponse, error)
	// FinalizeRegistrationRequest generates RegistrationRecord to store on server side.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-finalizeregistrationrequest
	FinalizeRegistrationRequest(password, serverIdentity, clientIdentity []byte, blind *eccgroup.Scalar, regRes *RegistrationResponse) (*RegistrationRecord, []byte, error)

	// AKE Functions
	//
	// ClientInit function begins the AKE protocol and produces the client's KE1 output for the server.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-clientinit
	ClientInit(password []byte) (*ClientLoginState, *KE1, error)
	// ServerInit function continues the AKE protocol by processing the client's KE1 message and producing the server's KE2 output.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-serverinit
	ServerInit(serverPrivKey *PrivateKey, serverPubKey *PublicKey, record *RegistrationRecord, ke1 *KE1, credIdentifier, clientIdentity, serverIdentity, oprfSeed []byte) (*ServerLoginState, *KE2, error)
	// The ClientFinish function completes the AKE protocol for the client and produces the client's KE3 output for the server, as well as the session_key and export_key outputs from the AKE.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-clientfinish
	ClientFinish(state *ClientLoginState, clientIdentity, serverIdentity []byte, ke2 *KE2) (*KE3, []byte, []byte, error)
	// The ServerFinish function completes the AKE protocol for the server, yielding the session_key.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-serverfinish
	ServerFinish(state *ServerLoginState, ke3 *KE3) ([]byte, error)

	// Credential Retrieval Functions
	//
	// The CreateCredentialRequest is used by the client to initiate the credential retrieval process, and it produces a CredentialRequest message and OPRF state.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-createcredentialrequest.
	CreateCredentialRequest(password []byte, chosenBlind *eccgroup.Scalar) (*CredentialRequest, *eccgroup.Scalar, error)
	// The CreateCredentialResponse function is used by the server to process the client's CredentialRequest message and complete the credential retrieval process, producing a CredentialResponse.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-createcredentialresponse.
	CreateCredentialResponse(credReq *CredentialRequest, serverPubKey *PublicKey, record *RegistrationRecord, credIdentifier, oprfSeed, maskingNonce []byte) (*CredentialResponse, error)
	// The RecoverCredentials function is used by the client to process the server's CredentialResponse message and produce the client's private key, server public key, and the export_key.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-recovercredentials.
	RecoverCredentials(password []byte, blind *eccgroup.Scalar, credRes *CredentialResponse, serverIdentity, clientIdentity []byte) (*PrivateKey, *PublicKey, []byte, error)

	// Key Creation Functions
	//
	// DeriveKeyPair wraps the DeriveKeyPair functionality of the OPRF suite used by opaque suite.
	DeriveKeyPair(seed []byte) (*PrivateKey, error)
	// GenerateKeyPair wraps the GenerateKeyPair functionality of the OPRF suite used by opaque suite.
	GenerateKeyPair() (*PrivateKey, error)
	// DeriveAuthKeyPair implements the steps found at https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-key-creation.
	DeriveAuthKeyPair(seed []byte) (*PrivateKey, error)
	// GenerateAuthKeyPair implements the steps found at https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-key-creation.
	GenerateAuthKeyPair() (*PrivateKey, error)

	// AKE 3DH Functions
	//
	// The function AuthClientStart implements OPAQUE-3DH AuthClientStart function.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-3dh-client-functions.
	// Unlike draft implementation, this function returns client state instead of managing it internally.
	AuthClientStart(credentialReq *CredentialRequest, clientNonce []byte, clientSecret *PrivateKey) (*ClientLoginState, *KE1, error)
	// The function AuthClientFinalize implements OPAQUE-3DH AuthClientFinalize function.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-3dh-client-functions.
	AuthClientFinalize(state *ClientLoginState, clientIdentity, serverIdentity []byte, cPrivKey *PrivateKey, sPubKey *PublicKey, ke2 *KE2) (*KE3, []byte, error)
	// The function AuthServerRespond implements OPAQUE-3DH AuthServerRespond function.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-3dh-server-functions.
	// Unlike draft implementation, this function returns server state instead of managing it internally.
	AuthServerRespond(serverPrivKey *PrivateKey, serverIdentity, clientIdentity, serverNonce []byte, clientPubKey *PublicKey, ke1 *KE1, credentialRes *CredentialResponse, serverPrivateKeyshare *PrivateKey) (*ServerLoginState, *AuthResponse, error)
	// The function AuthServerFinalize implements OPAQUE-3DH AuthServerFinalize function.
	// Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-09.html#name-3dh-server-functions.
	AuthServerFinalize(state *ServerLoginState, ke3 *KE3) ([]byte, error)

	// Dynamic Length Functions
	//
	// Output length of the Hash function used by opaque suite. (in byte)
	Nh() int
	// Output length of the public key generated by GenerateAuthKeyPair or DeriveAuthKeyPair functions. (in byte)
	Npk() int
	// Output length of the private key generated by GenerateAuthKeyPair or DeriveAuthKeyPair functions. (in byte)
	Nsk() int
	// Output length of MAC function. (in byte)
	Nm() int
	// Output length of Extract function. (in byte)
	Nx() int
	// Output length of serialized group element of the OPRF suite used by opaque suite.
	// In other words, output length of the public key generated by GenerateKeyPair or DeriveKeyPair functions. (in byte)
	Noe() int
	// Output length of serialized group scalar of the OPRF suite used by opaque suite.
	// In other words, output length of the private key generated by GenerateKeyPair or DeriveKeyPair functions. (in byte)
	Nok() int
	// Nonce length used in opaque protocol. (in byte)
	Nn() int
	// Seed length used in opaque protocol. (in byte)
	Nseed() int
	// Length of Envelope struct. (in byte)
	Ne() int
}

Suite interface identifies the opaque protocol and required functions

Directories

Path Synopsis
internal
common
Package common implements commonly used functions on the opaque package.
Package common implements commonly used functions on the opaque package.

Jump to

Keyboard shortcuts

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