package org.bouncycastle.pqc.jcajce.provider.newhope;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.ShortBufferException;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi;
import org.bouncycastle.pqc.crypto.ExchangePair;
import org.bouncycastle.pqc.crypto.newhope.NHAgreement;
import org.bouncycastle.pqc.crypto.newhope.NHExchangePairGenerator;
import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters;
import org.bouncycastle.util.Arrays;
public class KeyAgreementSpi
extends BaseAgreementSpi
{
private NHAgreement agreement;
private BCNHPublicKey otherPartyKey;
private NHExchangePairGenerator exchangePairGenerator;
private byte[] shared;
public KeyAgreementSpi()
{
super("NH", null);
}
protected void engineInit(Key key, SecureRandom secureRandom)
throws InvalidKeyException
{
if (key != null)
{
agreement = new NHAgreement();
agreement.init(((BCNHPrivateKey)key).getKeyParams());
}
else
{
exchangePairGenerator = new NHExchangePairGenerator(secureRandom);
}
}
protected void engineInit(Key key, AlgorithmParameterSpec algorithmParameterSpec, SecureRandom secureRandom)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
throw new InvalidAlgorithmParameterException("NewHope does not require parameters");
}
protected Key engineDoPhase(Key key, boolean lastPhase)
throws InvalidKeyException, IllegalStateException
{
if (!lastPhase)
{
throw new IllegalStateException("NewHope can only be between two parties.");
}
otherPartyKey = (BCNHPublicKey)key;
if (exchangePairGenerator != null)
{
ExchangePair exchPair = exchangePairGenerator.generateExchange((AsymmetricKeyParameter)otherPartyKey.getKeyParams());
shared = exchPair.getSharedValue();
return new BCNHPublicKey((NHPublicKeyParameters)exchPair.getPublicKey());
}
else
{
shared = agreement.calculateAgreement(otherPartyKey.getKeyParams());
return null;
}
}
protected byte[] engineGenerateSecret()
throws IllegalStateException
{
byte[] rv = Arrays.clone(shared);
Arrays.fill(shared, (byte)0);
return rv;
}
protected int engineGenerateSecret(byte[] bytes, int offset)
throws IllegalStateException, ShortBufferException
{
System.arraycopy(shared, 0, bytes, offset, shared.length);
Arrays.fill(shared, (byte)0);
return shared.length;
}
protected byte[] calcSecret()
{
return engineGenerateSecret();
}
}