Skip to content

Commit

Permalink
fix(core): validate public key on instantiating by `ErgoAddress.fromP…
Browse files Browse the repository at this point in the history
…ublicKey()`
  • Loading branch information
capt-nemo429 committed May 7, 2023
1 parent f4fb544 commit 0f1ffe5
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 4 deletions.
19 changes: 17 additions & 2 deletions packages/core/src/models/ergoAddress.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ describe("Encoding", () => {
describe("Address validation", () => {
it("Should not validate address (valid encoding but invalid PK)", () => {
expect(ErgoAddress.validate("9dg7gpByCWzoXdx5VeCvHeQYjx3q2TuTjzHqHfrsMsHszG49Rfj")).to.be.false;
expect(ErgoAddress.validate("2xgTiYUcGDwvJ41XhN2nxGajWkFa3xy9pXCMEKS8fwT8QpR19R")).to.be.false;
});

it("Should validate VALID address from encoded address string", () => {
Expand Down Expand Up @@ -269,20 +270,34 @@ describe("Public key", () => {
expect(ErgoAddress.fromBase58(FEE_MAINNET_ADDRESS_TV).getPublicKeys()).toHaveLength(0);
});

it("Should parse from public key hex string", () => {
it("Should create from public key hex string", () => {
for (const testVector of publicKeyTestVectors) {
expect(ErgoAddress.fromPublicKey(testVector.publicKey).toString()).toBe(testVector.base58);
}
});

it("Should parse from public key buffer", () => {
it("Should create from public key bytes", () => {
for (const testVector of publicKeyTestVectors) {
expect(ErgoAddress.fromPublicKey(hexToBytes(testVector.publicKey)).toString()).toBe(
testVector.base58
);
}
});

it("Should fail with invalid public keys", () => {
const invalidPKs = [
"01200a1c1b8fa17ec82de54bcaef96f23d7b34196c0410f6f578abdbf163b14b25", // not starting with 0x02 or 0x03
"09200a1c1b8fa17ec82de54bcaef96f23d7b34196c0410f6f578abdbf163b14b25", // not starting with 0x02 or 0x03
"02200a1c1b8fa17ec82de54bcaef96f23d7b34196c0410f6f578abdbf163b14b", // invalid length
"02200a1c1b8fa17ec82de54bcaef96f23d7b34196c041014b25f6f578abdbf163b1b", // invalid length
"000000000000000000000000000000000000000000000000000000000000000000" // infinity point
];

for (const pk of invalidPKs) {
expect(() => ErgoAddress.fromPublicKey(pk)).to.throw("The Public Key is invalid.");
}
});

it("Should generate the right public key from base58 encoded string", () => {
for (const testVector of publicKeyTestVectors) {
expect(bytesToHex(ErgoAddress.fromBase58(testVector.base58).getPublicKeys()[0])).toBe(
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/models/ergoAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ function _getErgoTreeType(ergoTree: Uint8Array): AddressType {
*
* `0x02` = compressed, positive Y coordinate.
* `0x03` = compressed, negative Y coordinate.
*
* @param pointBytes ECPoint bytes
*/
function _validateCompressedEcPoint(pointBytes: Uint8Array) {
Expand Down Expand Up @@ -122,7 +123,12 @@ export class ErgoAddress {
* @param publicKey Public key hex string
*/
public static fromPublicKey(publicKey: HexString | Uint8Array, network?: Network): ErgoAddress {
const ergoTree = concatBytes(P2PK_ERGOTREE_PREFIX, _ensureBytes(publicKey));
const bytes = _ensureBytes(publicKey);
if (!_validateCompressedEcPoint(bytes)) {
throw new Error("The Public Key is invalid.");
}

const ergoTree = concatBytes(P2PK_ERGOTREE_PREFIX, bytes);

return new ErgoAddress(ergoTree, network);
}
Expand Down
2 changes: 1 addition & 1 deletion vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default defineConfig({
reporter: ["text", "json", "html"],
lines: 100,
statements: 100,
branches: 98.39,
branches: 98.42,
functions: 100,
thresholdAutoUpdate: true,
exclude: ["**/tests/**", "**/*.spec.ts"]
Expand Down

0 comments on commit 0f1ffe5

Please sign in to comment.