package org.bouncycastle.crypto.agreement.owl;

import java.math.BigInteger;

import org.bouncycastle.math.ec.ECPoint;

/**
 * The final payload generated by the {@link OwlServerRegistration} during the user registration of a Owl exchange.
 * This payload is to be stored securely by the server.
 * <p>
 * Each {@link OwlServerRegistration} creates and sends an instance
 * of this payload to be stored securely.
 * The payload to send should be created via
 * {@link OwlServerRegistration#registerUseronServer(OwlInitialRegistration)}.
 */
public class OwlFinishRegistration
{
    /**
     * Unique identifier for the client in this registration phase.
     * <p>
     * Must be different to the server's unique identifier.
     * </p>
     */
    private final String clientId;

    /**
     * The value x3 * [G].
     */
    private final ECPoint gx3;

    /**
     * The zero knowledge proof for x3.
     * <p>
     * This is a class {@link ECSchnorrZKP} with two fields, containing {v*[G], r} for x3.
     * </p>
     */
    private final ECSchnorrZKP knowledgeProofForX3;

    /**
     * The value of pi = H(t), where t = H(Username||password) mod(n)
     */
    private final BigInteger pi;

    /**
     * The value of T = t * [G]
     */
    private final ECPoint gt;

    /**
     * Constructor of OwlFinishRegistration
     * @param clientId The client identity (or username)
     * @param knowledgeProofForX3 The zero-knowledge proof for the knowledge of x3 for X3
     * @param gx3 The public key X3= [G] * x3
     * @param pi pi = H(t) where t=H(username || password) mod n
     * @param gt T = t * [G]
     */
    public OwlFinishRegistration(
        String clientId,
        ECSchnorrZKP knowledgeProofForX3,
        ECPoint gx3,
        BigInteger pi,
        ECPoint gt)
    {
        OwlUtil.validateNotNull(clientId, "clientId");
        OwlUtil.validateNotNull(pi, "pi");
        OwlUtil.validateNotNull(gt, "gt");
        OwlUtil.validateNotNull(gx3, "gx3");
        OwlUtil.validateNotNull(knowledgeProofForX3, "knowledgeProofForX3");

        this.clientId = clientId;
        this.knowledgeProofForX3 = knowledgeProofForX3;
        this. gx3 = gx3;
        this.pi = pi;
        this.gt = gt;
    }
    
    /**
     * Get the client identity
     * @return The client identity
     */
    public String getClientId()
    {
        return clientId;
    }

    /**
     * Get pi = H(t), where t = H(Username||password) mod(n)
     * @return pi
     */
    public BigInteger getPi()
    {
        return pi;
    }

    /**
     * Get T = t * [G]
     * @return T
     */
    public ECPoint getGt()
    {
        return gt;
    }

    /**
     * Get X3 = x3 * [G]
     * @return X3
     */
    public ECPoint getGx3()
    {
        return gx3;
    }

    /**
     * Get the zero-knowledge proof for the knowledge of x3 for X3 = x3 * [G] 
     * @return {@link ECSchnorrZKP}
     */
    public ECSchnorrZKP getKnowledgeProofForX3()
    {
        return knowledgeProofForX3;
    }
}
