Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ES256Signer #240

Merged
merged 51 commits into from
Aug 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
aaedaf5
add ES256Signer Module
bshambaugh Jan 10, 2022
ae80a5a
update base58 test, it appears to have a problem
bshambaugh Jan 10, 2022
52646fd
update with failing test for base58
bshambaugh Jan 10, 2022
ac8e814
modify base58matcher to match both base58 in es256 and es256k
bshambaugh Jan 16, 2022
27fd5ea
change 68 to 86 in base58 matcher
bshambaugh Jan 16, 2022
3835342
remove uneccessary = sign in the base64 regex
bshambaugh Jan 16, 2022
7c26c1a
add ES256Signer to index so it is acessible
bshambaugh Jan 17, 2022
333fa55
refactor SignerAlgorithm.ts and SignerAlgorithm.test.ts by breaking u…
bshambaugh Jan 18, 2022
f9ed034
move tests for signers into folder called signers
bshambaugh Jan 18, 2022
85a5cbc
remove carriage returns (should be result of enter) and unused variab…
bshambaugh Jan 18, 2022
ac795f0
break up verifierAlgorithm into separate files bases on Curve
bshambaugh Jan 18, 2022
9d108ad
add preliminary tests for JWT
bshambaugh Jan 19, 2022
635eb7e
refactor VerifierAlgorithm test
bshambaugh Jan 20, 2022
622a7d1
update JWT tests
bshambaugh Jan 22, 2022
62e6f7d
update ES256Signer with constants
bshambaugh Jan 22, 2022
dcdeeb5
change the name of constants to common in JWT test folder
bshambaugh Jan 23, 2022
e498f41
add tests for JWT common
bshambaugh Jan 24, 2022
d8dccf9
add ES256 to Signer Verifier and JWT ...tests needed
bshambaugh Jan 24, 2022
61e9928
add note about supported key types in JWT, Signer, and Verifier Algor…
bshambaugh Jan 25, 2022
20c1ebe
in common_Signer_test_test.ts the create JWK functions need to be tes…
bshambaugh Feb 7, 2022
8b18d4e
added test to for comosmos adress from public key to keep consistent …
bshambaugh Mar 10, 2022
0c1c1fd
commit stub for decrypt / encrypt JWE Decrypter impl. for P-256
bshambaugh Mar 10, 2022
f312794
reverse base64matcher to original version that will match '=' sign, o…
bshambaugh Mar 22, 2022
8a38d4c
add a second matcher for base58 to util.test.ts to illustrate variabl…
bshambaugh Mar 27, 2022
027f701
remove encrypters and clean up to remote forks state
bshambaugh Apr 1, 2022
f39c88e
update util.ts with latest matcher
bshambaugh Apr 1, 2022
92e2bff
util.ts to fork
bshambaugh Apr 1, 2022
6dcb134
util.ts to fork try 2
bshambaugh Apr 1, 2022
9c0b48b
reset util.test.ts to fork
bshambaugh Apr 1, 2022
a0cd2a2
remove cosmos test because it is not upstream
bshambaugh Apr 1, 2022
c8fdae8
keep SignerAlgorithm the same as with upstream
bshambaugh Apr 1, 2022
71d970e
keep verifierAlgorithm.test.ts in line with upstream
bshambaugh Apr 1, 2022
358872d
set ES256KSigner.test.ts to upstream
bshambaugh Apr 1, 2022
f5a108a
change JWT.test.test to be in line with upstream
bshambaugh Apr 1, 2022
27f7f76
get VerifierAlgorithm in line with upstream
bshambaugh Apr 1, 2022
bc260fd
get SignerAlgorithm in line with upstream
bshambaugh Apr 1, 2022
e0f0e4f
update JWT.ts to be in line with upstream
bshambaugh Apr 1, 2022
28f04a7
update package.json to match upstream
bshambaugh Apr 1, 2022
17cba29
update package.json to match upstream try 2
bshambaugh Apr 1, 2022
c0b2791
add JWT.test.ts.snap
bshambaugh Apr 1, 2022
ca8a2e8
add yarn.lock to match upstream
bshambaugh Apr 1, 2022
129f566
remove parseKey from Signers as well as base64, 58, and hex matchers
bshambaugh Apr 1, 2022
b4fc0e2
remove commented out code with ES256KSigner.test.ts
bshambaugh Apr 1, 2022
9e4e33e
update README and export functions that convert hex, base64, and base…
bshambaugh Apr 2, 2022
dbf34ef
fix documentation for ES256KSigner
bshambaugh Apr 2, 2022
a2c7e6a
Merge remote-tracking branch 'upstream/master'
bshambaugh Aug 3, 2022
fa61104
remove extra line at the end of the files
bshambaugh Aug 5, 2022
a97d6a9
add newline to each of the files
bshambaugh Aug 5, 2022
a3b8fb4
create a ES256Signer
bshambaugh Aug 5, 2022
4e0a669
Add ES256Signer Tests
bshambaugh Aug 5, 2022
5b0cecf
update fixes suggested by linter
bshambaugh Aug 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions src/__tests__/ES256Signer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { hexToBytes, base58ToBytes, base64ToBytes } from '../util'
import { ES256Signer } from '../signers/ES256Signer'

describe('Secp256r1 Signer', () => {
it('signs data, given a hex private key', async () => {
expect.assertions(1)
const privateKey = '040f1dbf0a2ca86875447a7c010b0fc6d39d76859c458fbe8f2bf775a40ad74a'
const signer = ES256Signer(hexToBytes(privateKey))
const plaintext = 'thequickbrownfoxjumpedoverthelazyprogrammer'
await expect(signer(plaintext)).resolves.toEqual(
'vOTe64WujVUjEiQrAlwaPJtNADx4usSlCfe8OXHS6Np1BqJdqdJX912pVwVlAjmbqR_TMVE5i5TWB_GJVgrHgg'
)
})

it('signs data: privateKey with 0x prefix', async () => {
expect.assertions(1)
const privateKey = '0x040f1dbf0a2ca86875447a7c010b0fc6d39d76859c458fbe8f2bf775a40ad74a'
const signer = ES256Signer(hexToBytes(privateKey))
const plaintext = 'thequickbrownfoxjumpedoverthelazyprogrammer'
await expect(signer(plaintext)).resolves.toEqual(
'vOTe64WujVUjEiQrAlwaPJtNADx4usSlCfe8OXHS6Np1BqJdqdJX912pVwVlAjmbqR_TMVE5i5TWB_GJVgrHgg'
)
})

it('signs data: privateKey base58', async () => {
expect.assertions(1)
const privateKey = 'Gqzym8nfnxR5ZYZ3wZo8rvTwKTqGn5cJsbHnEhUZDPo'
const signer = ES256Signer(base58ToBytes(privateKey))
const plaintext = 'thequickbrownfoxjumpedoverthelazyprogrammer'
await expect(signer(plaintext)).resolves.toEqual(
'vOTe64WujVUjEiQrAlwaPJtNADx4usSlCfe8OXHS6Np1BqJdqdJX912pVwVlAjmbqR_TMVE5i5TWB_GJVgrHgg'
)
})

it('signs data: privateKey base64url', async () => {
expect.assertions(1)
const privateKey = 'BA8dvwosqGh1RHp8AQsPxtOddoWcRY--jyv3daQK10o'
const signer = ES256Signer(base64ToBytes(privateKey))
const plaintext = 'thequickbrownfoxjumpedoverthelazyprogrammer'
await expect(signer(plaintext)).resolves.toEqual(
'vOTe64WujVUjEiQrAlwaPJtNADx4usSlCfe8OXHS6Np1BqJdqdJX912pVwVlAjmbqR_TMVE5i5TWB_GJVgrHgg'
)
})

it('signs data: privateKey base64', async () => {
expect.assertions(1)
const privateKey = 'BA8dvwosqGh1RHp8AQsPxtOddoWcRY++jyv3daQK10o'
const signer = ES256Signer(base64ToBytes(privateKey))
const plaintext = 'thequickbrownfoxjumpedoverthelazyprogrammer'
await expect(signer(plaintext)).resolves.toEqual(
'vOTe64WujVUjEiQrAlwaPJtNADx4usSlCfe8OXHS6Np1BqJdqdJX912pVwVlAjmbqR_TMVE5i5TWB_GJVgrHgg'
)
})

it('refuses wrong key size (too short)', async () => {
expect.assertions(1)
const privateKey = '040f1dbf0a2ca86875447a7c010b0fc6d39d76859c458fbe8f2bf775a40ad7'
expect(() => {
ES256Signer(hexToBytes(privateKey))
}).toThrowError(/^bad_key: Invalid private key format.*/)
})

it('refuses wrong key size (double)', async () => {
expect.assertions(1)
const privateKey =
'040f1dbf0a2ca86875447a7c010b0fc6d39d76859c458fbe8f2bf775a40ad74a040f1dbf0a2ca86875447a7c010b0fc6d39d76859c458fbe8f2bf775a40ad74a'
expect(() => {
ES256Signer(hexToBytes(privateKey))
}).toThrowError(/^bad_key: Invalid private key format.*/)
})
})
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import SimpleSigner from './signers/SimpleSigner'
import EllipticSigner from './signers/EllipticSigner'
import NaclSigner from './signers/NaclSigner'
import { ES256KSigner } from './signers/ES256KSigner'
import { ES256Signer } from './signers/ES256Signer'
import { EdDSASigner } from './signers/EdDSASigner'
import {
verifyJWT,
Expand Down Expand Up @@ -35,6 +36,7 @@ export {
SimpleSigner,
EllipticSigner,
NaclSigner,
ES256Signer,
ES256KSigner,
EdDSASigner,
verifyJWT,
Expand Down
42 changes: 42 additions & 0 deletions src/signers/ES256Signer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { leftpad } from '../util'
import { toJose } from '../util'
import { Signer } from '../JWT'
import { sha256 } from '../Digest'
import elliptic from 'elliptic'

const secp256r1 = new elliptic.ec('p256')

/**
* Creates a configured signer function for signing data using the ES256K (secp256r1 + sha256) algorithm.
*
* The signing function itself takes the data as a `Uint8Array` or `string` and returns a `base64Url`-encoded signature
*
* @example
* ```typescript
* const sign: Signer = ES256Signer(process.env.PRIVATE_KEY)
* const signature: string = await sign(data)
* ```
*
* @param {String} privateKey a private key as `Uint8Array`
* @param {Boolean} recoverable an optional flag to add the recovery param to the generated signatures
* @return {Function} a configured signer function `(data: string | Uint8Array): Promise<string>`
*/
export function ES256Signer(privateKey: Uint8Array, recoverable = false): Signer {
const privateKeyBytes: Uint8Array = privateKey
if (privateKeyBytes.length !== 32) {
throw new Error(`bad_key: Invalid private key format. Expecting 32 bytes, but got ${privateKeyBytes.length}`)
}
const keyPair: elliptic.ec.KeyPair = secp256r1.keyFromPrivate(privateKeyBytes)

return async (data: string | Uint8Array): Promise<string> => {
const { r, s, recoveryParam }: elliptic.ec.Signature = keyPair.sign(sha256(data))
return toJose(
{
r: leftpad(r.toString('hex')),
s: leftpad(s.toString('hex')),
recoveryParam,
},
recoverable
)
}
}