evm-kms-signer 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,100 @@
1
+ import { DerParsingError } from '../errors';
2
+ /**
3
+ * Parse DER-encoded ECDSA signature into r and s components
4
+ *
5
+ * DER structure:
6
+ * SEQUENCE (0x30) [total_length]
7
+ * INTEGER (0x02) [r_length] [r_bytes]
8
+ * INTEGER (0x02) [s_length] [s_bytes]
9
+ *
10
+ * @param der - DER-encoded signature from AWS KMS
11
+ * @returns Object with r and s as 32-byte Uint8Arrays
12
+ * @throws DerParsingError if signature format is invalid
13
+ */
14
+ export function parseDerSignature(der) {
15
+ // Validate minimum length
16
+ if (der.length === 0) {
17
+ throw new DerParsingError('Invalid DER signature: empty buffer');
18
+ }
19
+ if (der.length < 8) {
20
+ throw new DerParsingError('Invalid DER signature: buffer too short');
21
+ }
22
+ // Validate SEQUENCE tag
23
+ if (der[0] !== 0x30) {
24
+ throw new DerParsingError('Invalid DER signature: expected SEQUENCE tag (0x30)');
25
+ }
26
+ const sequenceLength = der[1];
27
+ if (der.length < sequenceLength + 2) {
28
+ throw new DerParsingError('Invalid DER signature: SEQUENCE length exceeds buffer size');
29
+ }
30
+ let offset = 2; // Skip SEQUENCE tag and length
31
+ // Parse r INTEGER
32
+ if (offset >= der.length) {
33
+ throw new DerParsingError('Invalid DER signature: missing r INTEGER tag');
34
+ }
35
+ if (der[offset] !== 0x02) {
36
+ throw new DerParsingError('Invalid DER signature: expected INTEGER tag (0x02) for r');
37
+ }
38
+ offset++;
39
+ if (offset >= der.length) {
40
+ throw new DerParsingError('Invalid DER signature: missing r length');
41
+ }
42
+ let rLength = der[offset];
43
+ offset++;
44
+ // Validate r length
45
+ if (rLength === 0) {
46
+ throw new DerParsingError('Invalid DER signature: r length cannot be 0');
47
+ }
48
+ if (rLength > 33) {
49
+ throw new DerParsingError('Invalid DER signature: r length exceeds maximum (33 bytes)');
50
+ }
51
+ if (offset + rLength > der.length) {
52
+ throw new DerParsingError('Invalid DER signature: r value exceeds buffer length');
53
+ }
54
+ let r = der.slice(offset, offset + rLength);
55
+ // Remove leading 0x00 (negative number prevention padding)
56
+ if (rLength === 33 && r[0] === 0x00) {
57
+ r = r.slice(1);
58
+ }
59
+ // Left-pad with zeros to 32 bytes
60
+ if (r.length < 32) {
61
+ const padded = new Uint8Array(32);
62
+ padded.set(r, 32 - r.length);
63
+ r = padded;
64
+ }
65
+ offset += rLength;
66
+ // Parse s INTEGER
67
+ if (offset >= der.length) {
68
+ throw new DerParsingError('Invalid DER signature: missing s INTEGER tag');
69
+ }
70
+ if (der[offset] !== 0x02) {
71
+ throw new DerParsingError('Invalid DER signature: expected INTEGER tag (0x02) for s');
72
+ }
73
+ offset++;
74
+ if (offset >= der.length) {
75
+ throw new DerParsingError('Invalid DER signature: missing s length');
76
+ }
77
+ let sLength = der[offset];
78
+ offset++;
79
+ // Validate s length
80
+ if (sLength === 0) {
81
+ throw new DerParsingError('Invalid DER signature: s length cannot be 0');
82
+ }
83
+ if (sLength > 33) {
84
+ throw new DerParsingError('Invalid DER signature: s length exceeds maximum (33 bytes)');
85
+ }
86
+ if (offset + sLength > der.length) {
87
+ throw new DerParsingError('Invalid DER signature: s value exceeds buffer length');
88
+ }
89
+ let s = der.slice(offset, offset + sLength);
90
+ if (sLength === 33 && s[0] === 0x00) {
91
+ s = s.slice(1);
92
+ }
93
+ if (s.length < 32) {
94
+ const padded = new Uint8Array(32);
95
+ padded.set(s, 32 - s.length);
96
+ s = padded;
97
+ }
98
+ return { r, s };
99
+ }
100
+ //# sourceMappingURL=der.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"der.js","sourceRoot":"","sources":["../../src/utils/der.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ import type { Hex, Address } from 'viem';
2
+ /**
3
+ * secp256k1 curve order (n)
4
+ * Maximum value for ECDSA signature components r and s
5
+ */
6
+ export declare const SECP256K1_N = 115792089237316195423570985008687907852837564279074904382605163141518161494337n;
7
+ /**
8
+ * Half of secp256k1 curve order
9
+ * Used for EIP-2 signature normalization
10
+ */
11
+ export declare const SECP256K1_N_HALF: bigint;
12
+ /**
13
+ * Normalizes the s value of an ECDSA signature according to EIP-2.
14
+ *
15
+ * EIP-2 requires that s must be in the lower half of the curve order
16
+ * to prevent signature malleability attacks. If s > n/2, it is converted
17
+ * to s' = n - s.
18
+ *
19
+ * @param s - The s component of the ECDSA signature
20
+ * @returns The normalized s value
21
+ * @throws {SignatureNormalizationError} If s is out of valid range
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const s = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000001n
26
+ * const normalizedS = normalizeS(s)
27
+ * // normalizedS will be less than SECP256K1_N_HALF
28
+ * ```
29
+ */
30
+ export declare function normalizeS(s: bigint): bigint;
31
+ /**
32
+ * Calculates the recovery ID (0-3) for an ECDSA signature.
33
+ *
34
+ * The recovery ID is needed to recover the public key from a signature.
35
+ * This function tries all 4 possible recovery IDs and returns the one
36
+ * that produces a public key matching the expected address.
37
+ *
38
+ * @param messageHash - The hash of the signed message (32 bytes)
39
+ * @param r - The r component of the signature as hex string
40
+ * @param s - The s component of the signature as hex string
41
+ * @param expectedAddress - The expected Ethereum address
42
+ * @returns The recovery ID (0, 1, 2, or 3)
43
+ * @throws {RecoveryIdCalculationError} If no valid recovery ID is found
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const recoveryId = await calculateRecoveryId(
48
+ * '0x1234...', // message hash
49
+ * '0xabcd...', // r value
50
+ * '0xef01...', // s value
51
+ * '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb'
52
+ * )
53
+ * // recoveryId will be 0, 1, 2, or 3
54
+ * ```
55
+ */
56
+ export declare function calculateRecoveryId(messageHash: Hex, r: Hex, s: Hex, expectedAddress: Address): Promise<number>;
57
+ /**
58
+ * Calculates the v value for an ECDSA signature.
59
+ *
60
+ * The v value is used in Ethereum signatures to enable public key recovery.
61
+ * - Legacy (no chainId): v = 27 + recoveryId
62
+ * - EIP-155 (with chainId): v = chainId * 2 + 35 + recoveryId
63
+ *
64
+ * @param recoveryId - The recovery ID (0-3)
65
+ * @param chainId - Optional chain ID for EIP-155 signatures
66
+ * @returns The v value as bigint
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * // Legacy signature (no chain ID)
71
+ * const vLegacy = calculateV(0) // returns 27n
72
+ *
73
+ * // EIP-155 signature (with chain ID 1 for Ethereum mainnet)
74
+ * const vEIP155 = calculateV(0, 1) // returns 37n (1 * 2 + 35 + 0)
75
+ * ```
76
+ */
77
+ export declare function calculateV(recoveryId: number, chainId?: number): bigint;
78
+ /**
79
+ * Converts a Uint8Array to a bigint.
80
+ *
81
+ * This is useful for converting DER-encoded signature components
82
+ * (which are returned as Uint8Array) to bigint for cryptographic operations.
83
+ *
84
+ * @param arr - The Uint8Array to convert
85
+ * @returns The bigint representation
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * const bytes = new Uint8Array([0x01, 0x02, 0x03, 0x04])
90
+ * const value = uint8ArrayToBigInt(bytes)
91
+ * // value === 0x01020304n
92
+ * ```
93
+ */
94
+ export declare function uint8ArrayToBigInt(arr: Uint8Array): bigint;
95
+ //# sourceMappingURL=signature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature.d.ts","sourceRoot":"","sources":["../../src/utils/signature.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAIxC;;;GAGG;AACH,eAAO,MAAM,WAAW,kFAAsE,CAAA;AAE9F;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAmB,CAAA;AAEhD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAY5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,GAAG,EAChB,CAAC,EAAE,GAAG,EACN,CAAC,EAAE,GAAG,EACN,eAAe,EAAE,OAAO,GACvB,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAcvE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAY1D"}
@@ -0,0 +1,153 @@
1
+ import { recoverPublicKey, fromHex } from 'viem';
2
+ import { SignatureNormalizationError, RecoveryIdCalculationError } from '../errors';
3
+ import { publicKeyToAddress } from './address';
4
+ /**
5
+ * secp256k1 curve order (n)
6
+ * Maximum value for ECDSA signature components r and s
7
+ */
8
+ export const SECP256K1_N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n;
9
+ /**
10
+ * Half of secp256k1 curve order
11
+ * Used for EIP-2 signature normalization
12
+ */
13
+ export const SECP256K1_N_HALF = SECP256K1_N / 2n;
14
+ /**
15
+ * Normalizes the s value of an ECDSA signature according to EIP-2.
16
+ *
17
+ * EIP-2 requires that s must be in the lower half of the curve order
18
+ * to prevent signature malleability attacks. If s > n/2, it is converted
19
+ * to s' = n - s.
20
+ *
21
+ * @param s - The s component of the ECDSA signature
22
+ * @returns The normalized s value
23
+ * @throws {SignatureNormalizationError} If s is out of valid range
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const s = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000001n
28
+ * const normalizedS = normalizeS(s)
29
+ * // normalizedS will be less than SECP256K1_N_HALF
30
+ * ```
31
+ */
32
+ export function normalizeS(s) {
33
+ if (s <= 0n || s >= SECP256K1_N) {
34
+ throw new SignatureNormalizationError(`s value out of valid range (must be 0 < s < n): ${s.toString(16)}`);
35
+ }
36
+ if (s > SECP256K1_N_HALF) {
37
+ return SECP256K1_N - s;
38
+ }
39
+ return s;
40
+ }
41
+ /**
42
+ * Calculates the recovery ID (0-3) for an ECDSA signature.
43
+ *
44
+ * The recovery ID is needed to recover the public key from a signature.
45
+ * This function tries all 4 possible recovery IDs and returns the one
46
+ * that produces a public key matching the expected address.
47
+ *
48
+ * @param messageHash - The hash of the signed message (32 bytes)
49
+ * @param r - The r component of the signature as hex string
50
+ * @param s - The s component of the signature as hex string
51
+ * @param expectedAddress - The expected Ethereum address
52
+ * @returns The recovery ID (0, 1, 2, or 3)
53
+ * @throws {RecoveryIdCalculationError} If no valid recovery ID is found
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const recoveryId = await calculateRecoveryId(
58
+ * '0x1234...', // message hash
59
+ * '0xabcd...', // r value
60
+ * '0xef01...', // s value
61
+ * '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb'
62
+ * )
63
+ * // recoveryId will be 0, 1, 2, or 3
64
+ * ```
65
+ */
66
+ export async function calculateRecoveryId(messageHash, r, s, expectedAddress) {
67
+ for (let recoveryId = 0; recoveryId < 4; recoveryId++) {
68
+ try {
69
+ // Attempt to recover public key using this recovery ID
70
+ // Use legacy v value (27 + recoveryId) for recovery
71
+ const publicKey = await recoverPublicKey({
72
+ hash: messageHash,
73
+ signature: {
74
+ r,
75
+ s,
76
+ v: BigInt(27 + recoveryId)
77
+ }
78
+ });
79
+ // Calculate address from recovered public key
80
+ // recoverPublicKey returns Hex, convert to Uint8Array for publicKeyToAddress
81
+ const publicKeyBytes = fromHex(publicKey, 'bytes');
82
+ const address = publicKeyToAddress(publicKeyBytes);
83
+ // Compare with expected address (case-insensitive)
84
+ if (address.toLowerCase() === expectedAddress.toLowerCase()) {
85
+ return recoveryId;
86
+ }
87
+ }
88
+ catch {
89
+ // Recovery failed with this ID, try next one
90
+ continue;
91
+ }
92
+ }
93
+ throw new RecoveryIdCalculationError(`Cannot find valid recovery ID for signature (r=${r}, s=${s}) and address ${expectedAddress}`);
94
+ }
95
+ /**
96
+ * Calculates the v value for an ECDSA signature.
97
+ *
98
+ * The v value is used in Ethereum signatures to enable public key recovery.
99
+ * - Legacy (no chainId): v = 27 + recoveryId
100
+ * - EIP-155 (with chainId): v = chainId * 2 + 35 + recoveryId
101
+ *
102
+ * @param recoveryId - The recovery ID (0-3)
103
+ * @param chainId - Optional chain ID for EIP-155 signatures
104
+ * @returns The v value as bigint
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * // Legacy signature (no chain ID)
109
+ * const vLegacy = calculateV(0) // returns 27n
110
+ *
111
+ * // EIP-155 signature (with chain ID 1 for Ethereum mainnet)
112
+ * const vEIP155 = calculateV(0, 1) // returns 37n (1 * 2 + 35 + 0)
113
+ * ```
114
+ */
115
+ export function calculateV(recoveryId, chainId) {
116
+ if (recoveryId < 0 || recoveryId > 3) {
117
+ throw new RecoveryIdCalculationError(`Invalid recovery ID (must be 0-3): ${recoveryId}`);
118
+ }
119
+ if (chainId !== undefined) {
120
+ // EIP-155: v = chainId * 2 + 35 + recoveryId
121
+ return BigInt(chainId * 2 + 35 + recoveryId);
122
+ }
123
+ // Legacy: v = 27 + recoveryId
124
+ return BigInt(27 + recoveryId);
125
+ }
126
+ /**
127
+ * Converts a Uint8Array to a bigint.
128
+ *
129
+ * This is useful for converting DER-encoded signature components
130
+ * (which are returned as Uint8Array) to bigint for cryptographic operations.
131
+ *
132
+ * @param arr - The Uint8Array to convert
133
+ * @returns The bigint representation
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const bytes = new Uint8Array([0x01, 0x02, 0x03, 0x04])
138
+ * const value = uint8ArrayToBigInt(bytes)
139
+ * // value === 0x01020304n
140
+ * ```
141
+ */
142
+ export function uint8ArrayToBigInt(arr) {
143
+ if (arr.length === 0) {
144
+ return 0n;
145
+ }
146
+ // Convert Uint8Array to hex string
147
+ const hex = Array.from(arr)
148
+ .map(byte => byte.toString(16).padStart(2, '0'))
149
+ .join('');
150
+ // Parse as bigint
151
+ return BigInt('0x' + hex);
152
+ }
153
+ //# sourceMappingURL=signature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature.js","sourceRoot":"","sources":["../../src/utils/signature.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "evm-kms-signer",
3
+ "version": "1.0.0",
4
+ "description": "AWS KMS-based Ethereum signer for viem with enterprise-grade security. Sign transactions and messages using keys stored in AWS KMS without exposing private keys.",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "keywords": [
20
+ "ethereum",
21
+ "aws",
22
+ "kms",
23
+ "viem",
24
+ "signer",
25
+ "evm",
26
+ "crypto",
27
+ "blockchain",
28
+ "wallet",
29
+ "security"
30
+ ],
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/gtg7784/evm-kms-signer.git"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/gtg7784/evm-kms-signer/issues"
37
+ },
38
+ "homepage": "https://github.com/gtg7784/evm-kms-signer#readme",
39
+ "scripts": {
40
+ "type-check": "tsc --noEmit",
41
+ "start": "tsx src/index.ts",
42
+ "build": "tsc",
43
+ "test": "vitest",
44
+ "test:ui": "vitest --ui",
45
+ "test:run": "vitest run",
46
+ "example:sign": "tsx examples/sign-message.ts",
47
+ "example:tx": "tsx examples/send-transaction.ts"
48
+ },
49
+ "author": "Alan Go <tae.gun7784@gmail.com>",
50
+ "license": "MIT",
51
+ "engines": {
52
+ "node": ">=18.0.0"
53
+ },
54
+ "packageManager": "pnpm@9.0.1+sha1.0e0a9c2d140ddf9aab730067eb7bcfb9e18bdee7",
55
+ "peerDependencies": {
56
+ "viem": "^2.0.0"
57
+ },
58
+ "dependencies": {
59
+ "@aws-sdk/client-kms": "^3.0.0",
60
+ "abitype": "^1.1.1"
61
+ },
62
+ "devDependencies": {
63
+ "@types/node": "^24.10.0",
64
+ "dotenv": "^17.2.3",
65
+ "tsx": "^4.20.6",
66
+ "typescript": "^5.9.3",
67
+ "vitest": "^4.0.8",
68
+ "viem": "^2.0.0"
69
+ }
70
+ }