UNPKG

ox

Version:

Ethereum Standard Library

577 lines (529 loc) 18 kB
import { Bytes, PublicKey } from 'ox' import { describe, expect, test } from 'vp/test' test('exports', () => { expect(Object.keys(PublicKey)).toMatchInlineSnapshot(` [ "assert", "compress", "from", "fromBytes", "fromHex", "toBytes", "toHex", "validate", "InvalidError", "InvalidPrefixError", "InvalidCompressedPrefixError", "InvalidUncompressedPrefixError", "InvalidSerializedSizeError", ] `) }) describe('PublicKey.assert', () => { test('compressed', () => { PublicKey.assert({ prefix: 2, x: '0x0000000000000000000000000000000000000000000000000000000000000001', }) PublicKey.assert({ prefix: 3, x: '0x0000000000000000000000000000000000000000000000000000000000000001', }) expect(() => PublicKey.assert({ x: '0x0000000000000000000000000000000000000000000000000000000000000001', }), ).toThrowErrorMatchingInlineSnapshot( ` [PublicKey.InvalidPrefixError: Prefix "undefined" is invalid. Details: Prefix must be 2 or 3 for compressed public keys.] `, ) expect(() => PublicKey.assert({ prefix: 5, x: '0x0000000000000000000000000000000000000000000000000000000000000001', }), ).toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidPrefixError: Prefix "5" is invalid. Details: Prefix must be 2 or 3 for compressed public keys.] `) }) test('uncompressed', () => { PublicKey.assert({ prefix: 4, x: '0x0000000000000000000000000000000000000000000000000000000000000001', y: '0x0000000000000000000000000000000000000000000000000000000000000001', }) expect(() => PublicKey.assert({ x: '0x0000000000000000000000000000000000000000000000000000000000000001', y: '0x0000000000000000000000000000000000000000000000000000000000000001', }), ).toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidPrefixError: Prefix "undefined" is invalid. Details: Prefix must be 4 for uncompressed public keys.] `) expect(() => PublicKey.assert({ prefix: 3, x: '0x0000000000000000000000000000000000000000000000000000000000000001', y: '0x0000000000000000000000000000000000000000000000000000000000000001', }), ).toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidPrefixError: Prefix "3" is invalid. Details: Prefix must be 4 for uncompressed public keys.] `) expect(() => PublicKey.assert({ prefix: 5, x: '0x0000000000000000000000000000000000000000000000000000000000000001', y: '0x0000000000000000000000000000000000000000000000000000000000000001', }), ).toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidPrefixError: Prefix "5" is invalid. Details: Prefix must be 4 for uncompressed public keys.] `) }) test('unknown', () => { expect(() => PublicKey.assert({ y: '0x0000000000000000000000000000000000000000000000000000000000000001', }), ).toThrowErrorMatchingInlineSnapshot( ` [PublicKey.InvalidError: Value \`{"y":"0x0000000000000000000000000000000000000000000000000000000000000001"}\` is not a valid public key. Public key must contain: - an \`x\` and \`prefix\` value (compressed) - an \`x\`, \`y\`, and \`prefix\` value (uncompressed)] `, ) }) test('behavior: rejects missing x/y when compressed: false is set', () => { expect(() => PublicKey.assert({ prefix: 4 }, { compressed: false })) .toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidError: Value \`{"prefix":4}\` is not a valid public key. Public key must contain: - an \`x\` and \`prefix\` value (compressed) - an \`x\`, \`y\`, and \`prefix\` value (uncompressed)] `) expect(() => PublicKey.assert( { prefix: 4, x: '0x0000000000000000000000000000000000000000000000000000000000000001', }, { compressed: false }, ), ).toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidError: Value \`{"prefix":4,"x":"0x0000000000000000000000000000000000000000000000000000000000000001"}\` is not a valid public key. Public key must contain: - an \`x\` and \`prefix\` value (compressed) - an \`x\`, \`y\`, and \`prefix\` value (uncompressed)] `) }) test('behavior: rejects missing x or extra y when compressed: true is set', () => { expect(() => PublicKey.assert({ prefix: 2 }, { compressed: true })) .toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidError: Value \`{"prefix":2}\` is not a valid public key. Public key must contain: - an \`x\` and \`prefix\` value (compressed) - an \`x\`, \`y\`, and \`prefix\` value (uncompressed)] `) expect(() => PublicKey.assert( { prefix: 2, x: '0x0000000000000000000000000000000000000000000000000000000000000001', y: '0x0000000000000000000000000000000000000000000000000000000000000001', }, { compressed: true }, ), ).toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidError: Value \`{"prefix":2,"x":"0x0000000000000000000000000000000000000000000000000000000000000001","y":"0x0000000000000000000000000000000000000000000000000000000000000001"}\` is not a valid public key. Public key must contain: - an \`x\` and \`prefix\` value (compressed) - an \`x\`, \`y\`, and \`prefix\` value (uncompressed)] `) }) }) describe('PublicKey.compress', () => { test('default', () => { { const publicKey = PublicKey.compress({ prefix: 4, x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', y: '0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', }) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 3, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", } `) } { const publicKey = PublicKey.compress({ prefix: 4, x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', y: '0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa6', }) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 2, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", } `) } }) }) describe('PublicKey.fromHex', () => { test('default', () => { const serialized = '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5' const publicKey = PublicKey.fromHex(serialized) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 4, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", "y": "0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", } `) }) test('behavior: prefix', () => { const serialized = '0x048318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5' const publicKey = PublicKey.fromHex(serialized) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 4, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", "y": "0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", } `) }) test('behavior: compressed', () => { const serialized = '0x038318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75' const publicKey = PublicKey.fromHex(serialized) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 3, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", } `) }) test('error: invalid size', () => { expect(() => PublicKey.fromHex( '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2a', ), ).toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidSerializedSizeError: Value \`0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2a\` is an invalid public key size. Expected: 33 bytes (compressed + prefix), 64 bytes (uncompressed) or 65 bytes (uncompressed + prefix). Received 63 bytes.] `) }) test('error: invalid uncompressed prefix', () => { // 65-byte serialized with prefix 5 (invalid for uncompressed). expect(() => PublicKey.fromHex( '0x058318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', ), ).toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidPrefixError: Prefix "5" is invalid. Details: Prefix must be 4 for uncompressed public keys.] `) }) test('error: invalid compressed prefix', () => { // 33-byte serialized with prefix 5 (invalid for compressed). expect(() => PublicKey.fromHex( '0x058318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', ), ).toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidPrefixError: Prefix "5" is invalid. Details: Prefix must be 2 or 3 for compressed public keys.] `) }) }) describe('PublicKey.fromBytes', () => { test('default', () => { const serialized = Bytes.fromHex( '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', ) const publicKey = PublicKey.fromBytes(serialized) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 4, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", "y": "0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", } `) }) test('error: invalid prefix', () => { const serialized = Bytes.fromHex( '0x058318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', ) expect(() => PublicKey.fromBytes(serialized)) .toThrowErrorMatchingInlineSnapshot(` [PublicKey.InvalidPrefixError: Prefix "5" is invalid. Details: Prefix must be 4 for uncompressed public keys.] `) }) }) describe('PublicKey.from', () => { test('uncompressed', () => { const publicKey = PublicKey.from({ prefix: 4, x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', y: '0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', }) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 4, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", "y": "0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", } `) }) test('uncompressed, serialized hex', () => { const publicKey = PublicKey.from( '0x048318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', ) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 4, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", "y": "0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", } `) }) test('uncompressed, serialized bytes', () => { const publicKey = PublicKey.from( Bytes.fromHex( '0x048318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', ), ) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 4, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", "y": "0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", } `) }) test('uncompressed, no prefix', () => { const publicKey = PublicKey.from({ x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', y: '0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', }) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 4, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", "y": "0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", } `) }) test('uncompressed, no prefix, serialized hex', () => { const publicKey = PublicKey.from( '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', ) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 4, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", "y": "0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", } `) }) test('compressed', () => { const publicKey = PublicKey.from({ prefix: 3, x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', }) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 3, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", } `) }) test('compressed', () => { const publicKey = PublicKey.from({ prefix: 2, x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', }) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 2, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", } `) }) test('compressed, serialized hex', () => { const publicKey = PublicKey.from( '0x038318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', ) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 3, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", } `) }) test('compressed, serialized bytes', () => { const publicKey = PublicKey.from( Bytes.fromHex( '0x038318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', ), ) expect(publicKey).toMatchInlineSnapshot(` { "prefix": 3, "x": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", } `) }) }) describe('PublicKey.toHex', () => { test('default', () => { const publicKey = PublicKey.from({ x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', y: '0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', }) const serialized = PublicKey.toHex(publicKey) expect(serialized).toMatchInlineSnapshot( `"0x048318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5"`, ) }) test('behavior: prefix', () => { const publicKey = PublicKey.from({ prefix: 4, x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', y: '0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', }) const serialized = PublicKey.toHex(publicKey) expect(serialized).toMatchInlineSnapshot( `"0x048318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5"`, ) }) test('behavior: compressed', () => { const publicKey = PublicKey.from({ prefix: 3, x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', }) const serialized = PublicKey.toHex(publicKey) expect(serialized).toMatchInlineSnapshot( `"0x038318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75"`, ) }) test('option: includePrefix', () => { const publicKey = PublicKey.from({ x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', y: '0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', }) const serialized = PublicKey.toHex(publicKey, { includePrefix: false }) expect(serialized).toMatchInlineSnapshot( `"0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5"`, ) }) }) describe('PublicKey.toBytes', () => { test('default', () => { const publicKey = PublicKey.from({ x: '0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75', y: '0x3547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5', }) const serialized = PublicKey.toBytes(publicKey) expect(serialized).toMatchInlineSnapshot( ` Uint8Array [ 4, 131, 24, 83, 91, 84, 16, 93, 74, 122, 174, 96, 192, 143, 196, 95, 150, 135, 24, 27, 79, 223, 198, 37, 189, 26, 117, 63, 167, 57, 127, 237, 117, 53, 71, 241, 28, 168, 105, 102, 70, 242, 243, 172, 176, 142, 49, 1, 106, 250, 194, 62, 99, 12, 93, 17, 245, 159, 97, 254, 245, 123, 13, 42, 165, ] `, ) }) }) describe('PublicKey.validate', () => { test('default', () => { expect( PublicKey.validate({ prefix: 4, x: '0x6e100a352ec6ad1b70802290e18aeed190704973570f3b8ed42cb9808e2ea6bf', y: '0x6e100a352ec6ad1b70802290e18aeed190704973570f3b8ed42cb9808e2ea6bf', }), ).toBe(true) expect( PublicKey.validate({ prefix: 4, y: '0x6e100a352ec6ad1b70802290e18aeed190704973570f3b8ed42cb9808e2ea6bf', }), ).toBe(false) }) })