public byte[] getEncoded() {
    SubjectPublicKeyInfo info =
        new SubjectPublicKeyInfo(
            new AlgorithmIdentifier(
                OIWObjectIdentifiers.elGamalAlgorithm,
                new ElGamalParameter(elSpec.getP(), elSpec.getG()).getDERObject()),
            new DERInteger(y));

    return info.getDEREncoded();
  }
  JCEElGamalPublicKey(SubjectPublicKeyInfo info) {
    ElGamalParameter params =
        new ElGamalParameter((ASN1Sequence) info.getAlgorithmId().getParameters());
    DERInteger derY = null;

    try {
      derY = (DERInteger) info.getPublicKey();
    } catch (IOException e) {
      throw new IllegalArgumentException("invalid info structure in DSA public key");
    }

    this.y = derY.getValue();
    this.elSpec = new ElGamalParameterSpec(params.getP(), params.getG());
  }
  public byte[] getEncoded() {
    SubjectPublicKeyInfo info;
    byte[] keyEnc = this.getY().toByteArray();
    byte[] keyBytes;

    if (keyEnc[0] == 0) {
      keyBytes = new byte[keyEnc.length - 1];
    } else {
      keyBytes = new byte[keyEnc.length];
    }

    for (int i = 0; i != keyBytes.length; i++) {
      keyBytes[i] = keyEnc[keyEnc.length - 1 - i]; // must be little endian
    }

    if (gost3410Spec instanceof GOST3410ParameterSpec) {
      if (gost3410Spec.getEncryptionParamSetOID() != null) {
        info =
            new SubjectPublicKeyInfo(
                new AlgorithmIdentifier(
                    CryptoProObjectIdentifiers.gostR3410_94,
                    new GOST3410PublicKeyAlgParameters(
                            new DERObjectIdentifier(gost3410Spec.getPublicKeyParamSetOID()),
                            new DERObjectIdentifier(gost3410Spec.getDigestParamSetOID()),
                            new DERObjectIdentifier(gost3410Spec.getEncryptionParamSetOID()))
                        .getDERObject()),
                new DEROctetString(keyBytes));
      } else {
        info =
            new SubjectPublicKeyInfo(
                new AlgorithmIdentifier(
                    CryptoProObjectIdentifiers.gostR3410_94,
                    new GOST3410PublicKeyAlgParameters(
                            new DERObjectIdentifier(gost3410Spec.getPublicKeyParamSetOID()),
                            new DERObjectIdentifier(gost3410Spec.getDigestParamSetOID()))
                        .getDERObject()),
                new DEROctetString(keyBytes));
      }
    } else {
      info =
          new SubjectPublicKeyInfo(
              new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_94),
              new DEROctetString(keyBytes));
    }

    return info.getDEREncoded();
  }
  JDKGOST3410PublicKey(SubjectPublicKeyInfo info) {
    GOST3410PublicKeyAlgParameters params =
        new GOST3410PublicKeyAlgParameters((ASN1Sequence) info.getAlgorithmId().getParameters());
    DEROctetString derY;

    try {
      derY = (DEROctetString) info.getPublicKey();

      byte[] keyEnc = derY.getOctets();
      byte[] keyBytes = new byte[keyEnc.length];

      for (int i = 0; i != keyEnc.length; i++) {
        keyBytes[i] = keyEnc[keyEnc.length - 1 - i]; // was little endian
      }

      this.y = new BigInteger(1, keyBytes);
    } catch (IOException e) {
      throw new IllegalArgumentException("invalid info structure in GOST3410 public key");
    }

    this.gost3410Spec = GOST3410ParameterSpec.fromPublicKeyAlg(params);
  }