/** * Create a new public key fom given private keys. * * @param version of the public key / address * @param stream of the address * @param privateSigningKey private key used for signing * @param privateEncryptionKey private key used for encryption * @param nonceTrialsPerByte proof of work difficulty * @param extraBytes bytes to add for the proof of work (make it harder for small messages) * @param features of the address * @return a public key object */ public static Pubkey createPubkey(long version, long stream, byte[] privateSigningKey, byte[] privateEncryptionKey, long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) { return Factory.createPubkey(version, stream, createPublicKey(privateSigningKey).getEncoded(false), createPublicKey(privateEncryptionKey).getEncoded(false), nonceTrialsPerByte, extraBytes, features); }
public PrivateKey(boolean shorter, long stream, long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) { byte[] privSK; byte[] pubSK; byte[] privEK; byte[] pubEK; byte[] ripe; do { privSK = Security.randomBytes(PRIVATE_KEY_SIZE); privEK = Security.randomBytes(PRIVATE_KEY_SIZE); pubSK = Security.createPublicKey(privSK).getEncoded(false); pubEK = Security.createPublicKey(privEK).getEncoded(false); ripe = Pubkey.getRipe(pubSK, pubEK); } while (ripe[0] != 0 || (shorter && ripe[1] != 0)); this.privateSigningKey = privSK; this.privateEncryptionKey = privEK; this.pubkey = Security.createPubkey(Pubkey.LATEST_VERSION, stream, privateSigningKey, privateEncryptionKey, nonceTrialsPerByte, extraBytes, features); }
public void encrypt() throws IOException { encrypt(Security.createPublicKey(plaintext.getFrom().getPublicDecryptionKey()).getEncoded(false)); }
public static BitmessageAddress createIdentityFromPrivateKey(String address, byte[] privateSigningKey, byte[] privateEncryptionKey, long nonceTrialsPerByte, long extraBytes, int behaviourBitfield) { BitmessageAddress temp = new BitmessageAddress(address); PrivateKey privateKey = new PrivateKey(privateSigningKey, privateEncryptionKey, createPubkey(temp.getVersion(), temp.getStream(), Security.createPublicKey(privateSigningKey).getEncoded(false), Security.createPublicKey(privateEncryptionKey).getEncoded(false), nonceTrialsPerByte, extraBytes, behaviourBitfield)); BitmessageAddress result = new BitmessageAddress(privateKey); if (!result.getAddress().equals(address)) { throw new IllegalArgumentException("Address not matching private key. Address: " + address + "; Address derived from private key: " + result.getAddress()); } return result; }
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 void sendPubkey(BitmessageAddress identity, long targetStream) { try { long expires = UnixTime.now(+28 * DAY); LOG.info("Expires at " + expires); ObjectMessage response = new ObjectMessage.Builder() .stream(targetStream) .expiresTime(expires) .payload(identity.getPubkey()) .build(); response.sign(identity.getPrivateKey()); response.encrypt(Security.createPublicKey(identity.getPublicDecryptionKey()).getEncoded(false)); Security.doProofOfWork(response, proofOfWorkEngine, networkNonceTrialsPerByte, networkExtraBytes); if (response.isSigned()) { response.sign(identity.getPrivateKey()); } if (response instanceof Encrypted) { response.encrypt(Security.createPublicKey(identity.getPublicDecryptionKey()).getEncoded(false)); } inventory.storeObject(response); networkHandler.offer(response.getInventoryVector()); // TODO: save that the pubkey was just sent, and on which stream! } catch (IOException e) { throw new RuntimeException(e); } }