Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
/* istanbul ignore next */
throw new InvalidFormatError('Invalid NEP2 format when decoded from encryptedKey.');
}
const salt = decoded.slice(3, 7);
const derived = await getNEP2Derived({ password, salt });
const derived1 = derived.slice(0, 32);
const derived2 = derived.slice(32, 64);
const decipher = createDecipheriv(NEP2_CIPHER, derived2, Buffer.alloc(0, 0));
decipher.setAutoPadding(false);
decipher.end(decoded.slice(7, 7 + 32));
const plainText = decipher.read() as Buffer;
const privateKey = common.asPrivateKey(xor(plainText, derived1));
const addressSalt = getNEP2Salt({ addressVersion, privateKey });
if (!salt.equals(addressSalt)) {
/* istanbul ignore next */
throw new Error('Wrong passphrase.');
}
return common.bufferToPrivateKey(privateKey);
};
getDomain(state.fork, currentEpoch, Domain.PROPOSAL),
);
assert(blockSignatureVerified);
// RANDAO
const proposer = state.validatorRegistry[getBeaconProposerIndex(state, state.slot)];
const randaoRevealVerified = blsVerify(
proposer.pubkey,
intToBytes(currentEpoch, 32),
block.randaoReveal,
getDomain(state.fork, currentEpoch, Domain.PROPOSAL),
);
assert(randaoRevealVerified);
state.latestRandaoMixes[currentEpoch.modn(LATEST_RANDAO_MIXES_LENGTH)] =
xor(getRandaoMix(state, currentEpoch), hash(block.randaoReveal));
// Eth1 data
let eth1DataVote: Eth1DataVote = state.eth1DataVotes.find((vote) =>
vote.eth1Data.blockHash.equals(block.eth1Data.blockHash) &&
vote.eth1Data.depositRoot.equals(block.eth1Data.depositRoot));
if (eth1DataVote) {
eth1DataVote.voteCount = eth1DataVote.voteCount.addn(1);
} else {
state.eth1DataVotes.push({
eth1Data: block.eth1Data,
voteCount: new BN(1),
});
}
// Transactions
config: IBeaconConfig,
state: BeaconState,
body: BeaconBlockBody
): void {
const currentEpoch = getCurrentEpoch(config, state);
const proposer = state.validators[getBeaconProposerIndex(config, state)];
// Verify RANDAO reveal
assert(bls.verify(
proposer.pubkey,
hashTreeRoot(currentEpoch, config.types.Epoch),
body.randaoReveal,
getDomain(config, state, DomainType.RANDAO),
));
// Mix it in
state.randaoMixes[currentEpoch % config.params.EPOCHS_PER_HISTORICAL_VECTOR] =
xor(getRandaoMix(config, state, currentEpoch), hash(body.randaoReveal));
}
const derivedHalf2 = seedBPass.slice(32, 64);
const decipher = aes.createDecipheriv("aes-256-ecb", derivedHalf2, Buffer.alloc(0));
decipher.setAutoPadding(false);
decipher.end(encryptedPart2);
const decryptedPart2 = decipher.read();
const tmp = xor(decryptedPart2, derivedHalf1.slice(16, 32));
const seedBPart2 = tmp.slice(8, 16);
const decipher2 = aes.createDecipheriv("aes-256-ecb", derivedHalf2, Buffer.alloc(0));
decipher2.setAutoPadding(false);
decipher2.write(encryptedPart1); // first 8 bytes
decipher2.end(tmp.slice(0, 8)); // last 8 bytes
const seedBPart1 = xor(decipher2.read(), derivedHalf1.slice(0, 16));
const seedB = Buffer.concat([seedBPart1, seedBPart2], 24);
const privateKey = secp256k1.privateKeyTweakMul(HashAlgorithms.hash256(seedB), passFactor);
return {
privateKey,
compressed,
};
};
const encryptRaw = (buffer: Buffer, compressed: boolean, passphrase: string): Buffer => {
if (buffer.length !== 32) {
throw new PrivateKeyLengthError(32, buffer.length);
}
const address = getAddressPrivate(buffer, compressed);
const secret = Buffer.from(passphrase, "utf8");
const salt = HashAlgorithms.hash256(address).slice(0, 4);
const scryptBuf = crypto.scryptSync(secret, salt, 64, SCRYPT_PARAMS);
const derivedHalf1 = scryptBuf.slice(0, 32);
const derivedHalf2 = scryptBuf.slice(32, 64);
const xorBuf = xor(derivedHalf1, buffer);
const cipher = aes.createCipheriv("aes-256-ecb", derivedHalf2, NULL);
cipher.setAutoPadding(false);
cipher.end(xorBuf);
const cipherText = cipher.read();
// 0x01 | 0x42 | flagByte | salt (4) | cipherText (32)
const result = Buffer.allocUnsafe(7 + 32);
result.writeUInt8(0x01, 0);
result.writeUInt8(0x42, 1);
result.writeUInt8(compressed ? 0xe0 : 0xc0, 2);
salt.copy(result, 3);
cipherText.copy(result, 7);
return result;
};
if (!compressed && flagByte !== 0xc0) {
throw new Bip38CompressionError(0xc0, flagByte);
}
const salt = buffer.slice(3, 7);
const scryptBuf = crypto.scryptSync(passphrase, salt, 64, SCRYPT_PARAMS);
const derivedHalf1 = scryptBuf.slice(0, 32);
const derivedHalf2 = scryptBuf.slice(32, 64);
const privKeyBuf = buffer.slice(7, 7 + 32);
const decipher = aes.createDecipheriv("aes-256-ecb", derivedHalf2, NULL);
decipher.setAutoPadding(false);
decipher.end(privKeyBuf);
const plainText = decipher.read();
const privateKey = xor(derivedHalf1, plainText);
// verify salt matches address
const address = getAddressPrivate(privateKey, compressed);
const checksum = HashAlgorithms.hash256(address).slice(0, 4);
assert.deepEqual(salt, checksum);
return {
privateKey,
compressed,
};
};
const publicKey = getPublicKey(passFactor, true);
const seedBPass = crypto.scryptSync(publicKey, Buffer.concat([addressHash, ownerEntropy]), 64, {
N: 1024,
r: 1,
p: 1,
});
const derivedHalf1 = seedBPass.slice(0, 32);
const derivedHalf2 = seedBPass.slice(32, 64);
const decipher = aes.createDecipheriv("aes-256-ecb", derivedHalf2, Buffer.alloc(0));
decipher.setAutoPadding(false);
decipher.end(encryptedPart2);
const decryptedPart2 = decipher.read();
const tmp = xor(decryptedPart2, derivedHalf1.slice(16, 32));
const seedBPart2 = tmp.slice(8, 16);
const decipher2 = aes.createDecipheriv("aes-256-ecb", derivedHalf2, Buffer.alloc(0));
decipher2.setAutoPadding(false);
decipher2.write(encryptedPart1); // first 8 bytes
decipher2.end(tmp.slice(0, 8)); // last 8 bytes
const seedBPart1 = xor(decipher2.read(), derivedHalf1.slice(0, 16));
const seedB = Buffer.concat([seedBPart1, seedBPart2], 24);
const privateKey = secp256k1.privateKeyTweakMul(HashAlgorithms.hash256(seedB), passFactor);
return {
privateKey,
compressed,
};
};
privateKey,
}: {
readonly addressVersion: number;
readonly password: string;
readonly privateKey: PrivateKey;
}): Promise => {
const salt = getNEP2Salt({ addressVersion, privateKey });
const derived = await getNEP2Derived({ password, salt });
const derived1 = derived.slice(0, 32);
const derived2 = derived.slice(32, 64);
const cipher = createCipheriv(NEP2_CIPHER, derived2, Buffer.alloc(0, 0));
cipher.setAutoPadding(false);
cipher.end(xor(privateKey, derived1));
const ciphertext = cipher.read() as Buffer;
const result = Buffer.alloc(7 + 32, 0);
result.writeUInt8(NEP2_ZERO, 0);
result.writeUInt8(NEP2_ONE, 1);
result.writeUInt8(NEP2_TWO, 2);
salt.copy(result, 3);
ciphertext.copy(result, 7);
return base58CheckEncode(result);
};