-
Notifications
You must be signed in to change notification settings - Fork 249
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1355 from LimeChain/secp256k1-support-new
Add Secp256k1 support
- Loading branch information
Showing
24 changed files
with
6,324 additions
and
4,597 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
"@near-js/crypto": minor | ||
"@near-js/accounts": patch | ||
"@near-js/biometric-ed25519": patch | ||
"@near-js/keystores": patch | ||
"near-api-js": patch | ||
"@near-js/signers": patch | ||
"@near-js/transactions": patch | ||
"@near-js/wallet-account": patch | ||
--- | ||
|
||
Add Secp256k1 support |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
/** All supported key types */ | ||
export enum KeyType { | ||
ED25519 = 0, | ||
SECP256K1 = 1, | ||
} | ||
|
||
export enum KeySize { | ||
SECRET_KEY = 32 | ||
SECRET_KEY = 32, | ||
ED25519_PUBLIC_KEY = 32, | ||
SECP256k1_PUBLIC_KEY = 64, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
export { KeyType } from './constants'; | ||
export { KeyPair } from './key_pair'; | ||
export { KeyPair, KeyPairString } from './key_pair'; | ||
export { Signature } from './key_pair_base'; | ||
export { KeyPairEd25519 } from './key_pair_ed25519'; | ||
export { KeyPairSecp256k1 } from './key_pair_secp256k1'; | ||
export { PublicKey } from './public_key'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { KeySize, KeyType } from './constants'; | ||
import { KeyPairBase, Signature } from './key_pair_base'; | ||
import { PublicKey } from './public_key'; | ||
import secp256k1 from 'secp256k1'; | ||
import randombytes from 'randombytes'; | ||
import { KeyPairString } from './key_pair'; | ||
import { baseDecode, baseEncode } from '@near-js/utils'; | ||
/** | ||
* This class provides key pair functionality for secp256k1 curve: | ||
* generating key pairs, encoding key pairs, signing and verifying. | ||
* nearcore expects secp256k1 public keys to be 64 bytes at all times, | ||
* even when string encoded the secp256k1 library returns 65 byte keys | ||
* (including a 1 byte header that indicates how the pubkey was encoded). | ||
* We'll force the secp256k1 library to always encode uncompressed | ||
* keys with the corresponding 0x04 header byte, then manually | ||
* insert/remove that byte as needed. | ||
*/ | ||
export class KeyPairSecp256k1 extends KeyPairBase { | ||
readonly publicKey: PublicKey; | ||
readonly secretKey: string; | ||
readonly extendedSecretKey: string; | ||
|
||
/** | ||
* Construct an instance of key pair given a secret key. | ||
* It's generally assumed that these are encoded in base58. | ||
* @param {string} extendedSecretKey | ||
*/ | ||
constructor(extendedSecretKey: string) { | ||
super(); | ||
const decoded = baseDecode(extendedSecretKey); | ||
const secretKey = new Uint8Array(decoded.slice(0, KeySize.SECRET_KEY)); | ||
const withHeader = secp256k1.publicKeyCreate(new Uint8Array(secretKey), false); | ||
const data = withHeader.subarray(1, withHeader.length); // remove the 0x04 header byte | ||
this.publicKey = new PublicKey({ | ||
keyType: KeyType.SECP256K1, | ||
data | ||
}); | ||
this.secretKey = baseEncode(secretKey); | ||
this.extendedSecretKey = extendedSecretKey; | ||
} | ||
|
||
/** | ||
* Generate a new random keypair. | ||
* @example | ||
* const keyRandom = KeyPair.fromRandom(); | ||
* keyRandom.publicKey | ||
* // returns [PUBLIC_KEY] | ||
* | ||
* keyRandom.secretKey | ||
* // returns [SECRET_KEY] | ||
*/ | ||
static fromRandom() { | ||
// TODO: find better way to generate PK | ||
const secretKey = randombytes(KeySize.SECRET_KEY); | ||
const withHeader = secp256k1.publicKeyCreate(new Uint8Array(secretKey), false); | ||
const publicKey = withHeader.subarray(1, withHeader.length); | ||
const extendedSecretKey = new Uint8Array([...secretKey, ...publicKey]); | ||
return new KeyPairSecp256k1(baseEncode(extendedSecretKey)); | ||
} | ||
|
||
sign(message: Uint8Array): Signature { | ||
// nearcore expects 65 byte signatures formed by appending the recovery id to the 64 byte signature | ||
const { signature, recid } = secp256k1.ecdsaSign(message, baseDecode(this.secretKey)); | ||
return { signature: new Uint8Array([...signature, recid]), publicKey: this.publicKey }; | ||
} | ||
|
||
verify(message: Uint8Array, signature: Uint8Array): boolean { | ||
return this.publicKey.verify(message, signature); | ||
} | ||
|
||
toString(): KeyPairString { | ||
return `secp256k1:${this.extendedSecretKey}`; | ||
} | ||
|
||
getPublicKey(): PublicKey { | ||
return this.publicKey; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.