// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package com.google.crypto.tink.subtle;

import com.google.crypto.tink.util.Bytes;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;

/**
 * HKDF-based ECIES-KEM (key encapsulation mechanism) for ECIES sender.
 *
 * @since 1.0.0
 */
public final class EciesHkdfSenderKem {
  private final ECPublicKey recipientPublicKey;

  /** A container for key parts generated by the KEM. */
  public static final class KemKey {
    private final Bytes kemBytes;
    private final Bytes symmetricKey;

    public KemKey(final byte[] kemBytes, final byte[] symmetricKey) {
      if (kemBytes == null) {
        throw new NullPointerException("KemBytes must be non-null");
      }
      if (symmetricKey == null) {
        throw new NullPointerException("symmetricKey must be non-null");
      }
      this.kemBytes = Bytes.copyFrom(kemBytes);
      this.symmetricKey = Bytes.copyFrom(symmetricKey);
    }

    public byte[] getKemBytes() {
      return kemBytes.toByteArray();
    }

    public byte[] getSymmetricKey() {
      return symmetricKey.toByteArray();
    }
  }

  public EciesHkdfSenderKem(final ECPublicKey recipientPublicKey) {
    this.recipientPublicKey = recipientPublicKey;
  }

  public KemKey generateKey(
      String hmacAlgo,
      final byte[] hkdfSalt,
      final byte[] hkdfInfo,
      int keySizeInBytes,
      EllipticCurves.PointFormatType pointFormat)
      throws GeneralSecurityException {
    KeyPair ephemeralKeyPair = EllipticCurves.generateKeyPair(recipientPublicKey.getParams());
    ECPublicKey ephemeralPublicKey = (ECPublicKey) ephemeralKeyPair.getPublic();
    ECPrivateKey ephemeralPrivateKey = (ECPrivateKey) ephemeralKeyPair.getPrivate();
    byte[] sharedSecret = EllipticCurves.computeSharedSecret(
        ephemeralPrivateKey, recipientPublicKey);
    byte[] kemBytes =
        EllipticCurves.pointEncode(
            ephemeralPublicKey.getParams().getCurve(), pointFormat, ephemeralPublicKey.getW());
    byte[] symmetricKey =
        Hkdf.computeEciesHkdfSymmetricKey(
            kemBytes, sharedSecret, hmacAlgo, hkdfSalt, hkdfInfo, keySizeInBytes);
    return new KemKey(kemBytes, symmetricKey);
  }
}
