private void addFieldElement(Digest digest, ECFieldElement v) { byte[] p = v.getEncoded(); digest.update(p, 0, p.length); }
private void addFieldElement(Digest digest, ECFieldElement v) { byte[] p = v.getEncoded(); digest.update(p, 0, p.length); }
public static void writeECFieldElement(ECFieldElement x, OutputStream output) throws IOException { TlsUtils.writeOpaque8(x.getEncoded(), output); }
private static void addFieldElement(Digest digest, ECFieldElement element) { byte[] encoded = element.getEncoded(); digest.update(encoded, 0, encoded.length); }
public static void writeECFieldElement(ECFieldElement x, OutputStream output) throws IOException { TlsUtils.writeOpaque8(x.getEncoded(), output); }
public byte[] yEncoded() { return Q.getYCoord().getEncoded(); }
public byte[] xEncoded() { return Q.getXCoord().getEncoded(); }
private void writeCoordinateComponent(OutputStream out, ECFieldElement coord) throws IOException { byte[] x = coord.getEncoded(); int offset = Bytes.numberOfLeadingZeros(x); int length = x.length - offset; Encode.int16(length, out); out.write(x, offset, length); }
/** * UAF_ALG_KEY_ECC_X962_RAW 0x100 Raw ANSI X9.62 formatted Elliptic Curve * public key [SEC1]. * * I.e. [0x04, X (32 bytes), Y (32 bytes)]. Where the byte 0x04 denotes the * uncompressed point compression method. * * @param pub * - Public Key * @return bytes * @throws IOException */ public static byte[] getKeyAsRawBytes(BCECPublicKey pub) throws IOException { byte[] raw; ByteArrayOutputStream bos = new ByteArrayOutputStream(65); bos.write(0x04); bos.write(pub.getQ().getXCoord().getEncoded()); bos.write(pub.getQ().getYCoord().getEncoded()); raw = bos.toByteArray(); logger.info("Raw key length:" + raw.length); return raw; }
/** * UAF_ALG_KEY_ECC_X962_RAW 0x100 Raw ANSI X9.62 formatted Elliptic Curve * public key [SEC1]. * * I.e. [0x04, X (32 bytes), Y (32 bytes)]. Where the byte 0x04 denotes the * uncompressed point compression method. * * @param pub * - Public Key * @return bytes * @throws IOException */ public static byte[] getKeyAsRawBytes(BCECPublicKey pub) throws IOException { byte[] raw; ByteArrayOutputStream bos = new ByteArrayOutputStream(65); bos.write(0x04); bos.write(pub.getQ().getXCoord().getEncoded()); bos.write(pub.getQ().getYCoord().getEncoded()); raw = bos.toByteArray(); logger.info("Raw key length:" + raw.length); return raw; }
/** * Get an encoding of the point value, optionally in compressed format. * * @param compressed whether to generate a compressed point encoding. * @return the point encoding */ public byte[] getEncoded(boolean compressed) { if (this.isInfinity()) { return new byte[1]; } ECPoint normed = normalize(); byte[] X = normed.getXCoord().getEncoded(); if (compressed) { byte[] PO = new byte[X.length + 1]; PO[0] = (byte)(normed.getCompressionYTilde() ? 0x03 : 0x02); System.arraycopy(X, 0, PO, 1, X.length); return PO; } byte[] Y = normed.getYCoord().getEncoded(); byte[] PO = new byte[X.length + Y.length + 1]; PO[0] = 0x04; System.arraycopy(X, 0, PO, 1, X.length); System.arraycopy(Y, 0, PO, X.length + 1, Y.length); return PO; }
public byte[] agreement(BigInteger d) { // TODO thread safety of ECPoint unclear. synchronized (lock) { ECPoint P = Q.multiply(d).normalize(); if (P.isInfinity()) { throw new IllegalStateException("invalid EDCH: infinity"); } return P.getAffineXCoord().getEncoded(); } }
/** * @param privateKey a private key, typically should be 32 bytes long * @return an InputStream yielding the decrypted data * @throws DecryptionFailedException if the payload can't be decrypted using this private key * @see <a href='https://bitmessage.org/wiki/Encryption#Decryption'>https://bitmessage.org/wiki/Encryption#Decryption</a> */ public InputStream decrypt(byte[] privateKey) throws DecryptionFailedException { // 1. The private key used to decrypt is called k. BigInteger k = Security.keyToBigInt(privateKey); // 2. Do an EC point multiply with private key k and public key R. This gives you public key P. ECPoint P = R.multiply(k).normalize(); // 3. Use the X component of public key P and calculate the SHA512 hash H. byte[] H = Security.sha512(P.getXCoord().getEncoded()); // 4. The first 32 bytes of H are called key_e and the last 32 bytes are called key_m. byte[] key_e = Arrays.copyOfRange(H, 0, 32); byte[] key_m = Arrays.copyOfRange(H, 32, 64); // 5. Calculate MAC' with HMACSHA256, using key_m as salt and IV + R + cipher text as data. // 6. Compare MAC with MAC'. If not equal, decryption will fail. if (!Arrays.equals(mac, calculateMac(key_m))) { throw new DecryptionFailedException(); } // 7. Decrypt the cipher text with AES-256-CBC, using IV as initialization vector, key_e as decryption key // and the cipher text as payload. The output is the padded input text. return new ByteArrayInputStream(crypt(false, encrypted, key_e)); }
public static String generateKeyFingerprint(ECPoint publicPoint, org.bouncycastle.jce.spec.ECParameterSpec spec) { ECCurve curve = spec.getCurve(); ECPoint g = spec.getG(); if (curve != null) { return new Fingerprint(Arrays.concatenate(publicPoint.getEncoded(false), curve.getA().getEncoded(), curve.getB().getEncoded(), g.getEncoded(false))).toString(); } return new Fingerprint(publicPoint.getEncoded(false)).toString(); } }
public CryptoBox(Streamable data, ECPoint K) throws IOException { curveType = 0x02CA; // 1. The destination public key is called K. // 2. Generate 16 random bytes using a secure random number generator. Call them IV. initializationVector = Security.randomBytes(16); // 3. Generate a new random EC key pair with private key called r and public key called R. byte[] r = Security.randomBytes(PRIVATE_KEY_SIZE); R = Security.createPublicKey(r); // 4. Do an EC point multiply with public key K and private key r. This gives you public key P. ECPoint P = K.multiply(Security.keyToBigInt(r)).normalize(); byte[] X = P.getXCoord().getEncoded(); // 5. Use the X component of public key P and calculate the SHA512 hash H. byte[] H = Security.sha512(X); // 6. The first 32 bytes of H are called key_e and the last 32 bytes are called key_m. byte[] key_e = Arrays.copyOfRange(H, 0, 32); byte[] key_m = Arrays.copyOfRange(H, 32, 64); // 7. Pad the input text to a multiple of 16 bytes, in accordance to PKCS7. // 8. Encrypt the data with AES-256-CBC, using IV as initialization vector, key_e as encryption key and the padded input text as payload. Call the output cipher text. encrypted = crypt(true, Encode.bytes(data), key_e); // 9. Calculate a 32 byte MAC with HMACSHA256, using key_m as salt and IV + R + cipher text as data. Call the output MAC. mac = calculateMac(key_m); // The resulting data is: IV + R + cipher text + MAC }
public static byte[] encodePoint(ECPoint Q) { /*if (!Q.isCompressed()) Q=new ECPoint.F2m(Q.getCurve(),Q.getX(),Q.getY(),true); byte[] bytes=Q.getEncoded(); if (bytes[0]==0x02) bytes[bytes.length-1]&=0xFE; else if (bytes[0]==0x02) bytes[bytes.length-1]|=0x01; return Arrays.copyOfRange(bytes, 1, bytes.length);*/ Q = Q.normalize(); ECFieldElement x = Q.getAffineXCoord(); byte[] bytes = x.getEncoded(); if (!x.isZero()) { ECFieldElement z = Q.getAffineYCoord().divide(x); if (trace(z).isOne()) { bytes[bytes.length - 1] |= 0x01; } else { bytes[bytes.length - 1] &= 0xFE; } } return bytes; }
public static byte[] encodePoint(ECPoint Q) { /*if (!Q.isCompressed()) Q=new ECPoint.F2m(Q.getCurve(),Q.getX(),Q.getY(),true); byte[] bytes=Q.getEncoded(); if (bytes[0]==0x02) bytes[bytes.length-1]&=0xFE; else if (bytes[0]==0x02) bytes[bytes.length-1]|=0x01; return Arrays.copyOfRange(bytes, 1, bytes.length);*/ Q = Q.normalize(); ECFieldElement x = Q.getAffineXCoord(); byte[] bytes = x.getEncoded(); if (!x.isZero()) { ECFieldElement z = Q.getAffineYCoord().divide(x); if (trace(z).isOne()) { bytes[bytes.length - 1] |= 0x01; } else { bytes[bytes.length - 1] &= 0xFE; } } return bytes; }
public DSTU4145ECBinary(ECDomainParameters params) { ECCurve curve = params.getCurve(); if (!ECAlgorithms.isF2mCurve(curve)) { throw new IllegalArgumentException("only binary domain is possible"); } // We always use big-endian in parameter encoding PolynomialExtensionField field = (PolynomialExtensionField)curve.getField(); int[] exponents = field.getMinimalPolynomial().getExponentsPresent(); if (exponents.length == 3) { f = new DSTU4145BinaryField(exponents[2], exponents[1]); } else if (exponents.length == 5) { f = new DSTU4145BinaryField(exponents[4], exponents[1], exponents[2], exponents[3]); } else { throw new IllegalArgumentException("curve must have a trinomial or pentanomial basis"); } a = new ASN1Integer(curve.getA().toBigInteger()); b = new DEROctetString(curve.getB().getEncoded()); n = new ASN1Integer(params.getN()); bp = new DEROctetString(DSTU4145PointEncoder.encodePoint(params.getG())); }
public byte[] apply(ECPoint S, byte[] fingerprint) throws IOException { // RFC Sections 7, 8 byte[] ZB = S.getAffineXCoord().getEncoded(); Digest digest = digestFactory.get(); digest.update((byte) 0x00); // 00 digest.update((byte) 0x00); // 00 digest.update((byte) 0x00); // 00 digest.update((byte) 0x01); // 01 digest.update(ZB, 0, ZB.length); // ZB // Params digest.update(formattedOid, 0, formattedOid.length); // curve_OID_len || curve_OID digest.update(publicKeyAlgID); // public_key_alg_ID digest.update((byte) 0x03); // 03 digest.update((byte) 0x01); // 01 digest.update(kdfHashID); // KDF_hash_ID digest.update(symAlgID); // KEK_alg_ID for AESKeyWrap digest.update(ANONYMOUS_SENDER, 0, ANONYMOUS_SENDER.length); // "Anonymous Sender " digest.update(fingerprint, 0, fingerprint.length); // recipient_fingerprint byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); return hash; }
public DSTU4145ECBinary(ECDomainParameters params) { ECCurve curve = params.getCurve(); if (!ECAlgorithms.isF2mCurve(curve)) { throw new IllegalArgumentException("only binary domain is possible"); } // We always use big-endian in parameter encoding PolynomialExtensionField field = (PolynomialExtensionField)curve.getField(); int[] exponents = field.getMinimalPolynomial().getExponentsPresent(); if (exponents.length == 3) { f = new DSTU4145BinaryField(exponents[2], exponents[1]); } else if (exponents.length == 5) { f = new DSTU4145BinaryField(exponents[4], exponents[1], exponents[2], exponents[3]); } a = new ASN1Integer(curve.getA().toBigInteger()); b = new DEROctetString(curve.getB().getEncoded()); n = new ASN1Integer(params.getN()); bp = new DEROctetString(DSTU4145PointEncoder.encodePoint(params.getG())); }