mirror of
https://github.com/fluencelabs/fluence-js.git
synced 2024-12-05 02:10:18 +00:00
KeyPair: add fromBytes, toEd25519PrivateKey (#78)
- fromBytes allows to pass any seed you want - constructor takes PeerId (previously was empty and maybe private) - toEd25519PrivateKey to complete the lifecycle.
This commit is contained in:
parent
608506db9f
commit
763e641fa2
8
.github/workflows/publish_branch.yml
vendored
8
.github/workflows/publish_branch.yml
vendored
@ -17,9 +17,11 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Extract branch name
|
||||
run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_ENV
|
||||
|
||||
- name: Get branch name
|
||||
run: |
|
||||
BRANCH=${GITHUB_REF#refs/*/}
|
||||
SANITIZED=$(echo "$BRANCH" | sed -e 's/[^a-zA-Z0-9-]/-/g')
|
||||
echo "BRANCH_NAME=$SANITIZED" >> $GITHUB_ENV
|
||||
### Set version
|
||||
- name: Set version
|
||||
run: npm version prerelease --no-git-tag-version --preid ${{ env.BRANCH_NAME }}-${{ github.run_number }}
|
||||
|
8348
package-lock.json
generated
8348
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,6 @@
|
||||
"libp2p-websockets": "0.16.1",
|
||||
"loglevel": "1.7.0",
|
||||
"multiaddr": "10.0.0",
|
||||
"noble-ed25519": "^1.2.5",
|
||||
"peer-id": "0.15.3",
|
||||
"uuid": "8.3.0"
|
||||
},
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { encode } from 'bs58';
|
||||
import * as bs58 from 'bs58';
|
||||
import * as base64 from 'base64-js';
|
||||
import PeerId from 'peer-id';
|
||||
import { KeyPair } from '../../internal/KeyPair';
|
||||
|
||||
describe('KeyPair tests', () => {
|
||||
@ -10,23 +9,48 @@ describe('KeyPair tests', () => {
|
||||
|
||||
// act
|
||||
const keyPair = await KeyPair.fromEd25519SK(sk);
|
||||
const sk2 = peerIdToEd25519SK(keyPair.Libp2pPeerId);
|
||||
const privateKey = keyPair.toEd25519PrivateKey();
|
||||
const sk2 = base64.fromByteArray(privateKey)
|
||||
|
||||
// assert
|
||||
expect(sk2).toBe(sk);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Converts peer id into base64 string contatining the 32 byte Ed25519S secret key
|
||||
* @returns - base64 of Ed25519S secret key
|
||||
*/
|
||||
export const peerIdToEd25519SK = (peerId: PeerId): string => {
|
||||
// export as [...private, ...public] array
|
||||
const privateAndPublicKeysArray = peerId.privKey.marshal();
|
||||
// extract the private key
|
||||
const pk = privateAndPublicKeysArray.slice(0, 32);
|
||||
// serialize private key as base64
|
||||
const b64 = base64.fromByteArray(pk);
|
||||
return b64;
|
||||
};
|
||||
it('generate keypair from seed', async function () {
|
||||
// arrange
|
||||
const random = await KeyPair.randomEd25519();
|
||||
const privateKey = random.toEd25519PrivateKey();
|
||||
|
||||
// act
|
||||
const keyPair = await KeyPair.fromBytes(privateKey);
|
||||
const privateKey2 = keyPair.toEd25519PrivateKey();
|
||||
|
||||
// assert
|
||||
expect(privateKey).toStrictEqual(privateKey2);
|
||||
});
|
||||
|
||||
it('create keypair from ed25519 private key', async function() {
|
||||
// arrange
|
||||
const rustSK = "jDaxLJzYtzgwTMrELJCAqavtmx85ktQNfB2rLcK7MhH";
|
||||
const sk = bs58.decode(rustSK);
|
||||
|
||||
// act
|
||||
const keyPair = await KeyPair.fromBytes(sk);
|
||||
|
||||
// assert
|
||||
const expectedPeerId = "12D3KooWH1W3VznVZ87JH4FwABK4mkntcspTVWJDta6c2xg9Pzbp";
|
||||
expect(keyPair.Libp2pPeerId.toB58String()).toStrictEqual(expectedPeerId);
|
||||
});
|
||||
|
||||
it('create keypair from a seed phrase', async function() {
|
||||
// arrange
|
||||
const seedArray = new Uint8Array(32).fill(1);
|
||||
|
||||
// act
|
||||
const keyPair = await KeyPair.fromBytes(seedArray);
|
||||
|
||||
// assert
|
||||
const expectedPeerId = "12D3KooWK99VoVxNE7XzyBwXEzW7xhK7Gpv85r9F3V3fyKSUKPH5";
|
||||
expect(keyPair.Libp2pPeerId.toB58String()).toStrictEqual(expectedPeerId);
|
||||
});
|
||||
});
|
||||
|
@ -16,45 +16,53 @@
|
||||
|
||||
import * as PeerId from 'peer-id';
|
||||
import * as base64 from 'base64-js';
|
||||
import * as ed from 'noble-ed25519';
|
||||
import { keys } from 'libp2p-crypto';
|
||||
|
||||
export class KeyPair {
|
||||
/**
|
||||
* @deprecated
|
||||
* Key pair in libp2p format. Used for backward compatibility with the current FluencePeer implementation
|
||||
*/
|
||||
public Libp2pPeerId: PeerId;
|
||||
|
||||
/**
|
||||
* Generates a new KeyPair from base64 string contatining the 32 byte Ed25519 secret key
|
||||
* @returns - Promise with the created KeyPair
|
||||
*/
|
||||
static async fromEd25519SK(sk: string): Promise<KeyPair> {
|
||||
// deserialize secret key from base64
|
||||
const bytes = base64.toByteArray(sk);
|
||||
// calculate ed25519 public key
|
||||
const publicKey = await ed.getPublicKey(bytes);
|
||||
// concatenate secret + public because that's what libp2p-crypto expects
|
||||
const privateAndPublicKeysArray = new Uint8Array([...bytes, ...publicKey]);
|
||||
// deserialize keys.supportedKeys.Ed25519PrivateKey
|
||||
const privateKey = await keys.supportedKeys.ed25519.unmarshalEd25519PrivateKey(privateAndPublicKeysArray);
|
||||
// serialize it to protobuf encoding because that's what PeerId expects
|
||||
const protobuf = keys.marshalPrivateKey(privateKey);
|
||||
// deserialize PeerId from protobuf encoding
|
||||
const lib2p2Pid = await PeerId.createFromPrivKey(protobuf);
|
||||
const res = new KeyPair();
|
||||
res.Libp2pPeerId = lib2p2Pid;
|
||||
return res;
|
||||
constructor(libp2pPeerId: PeerId) {
|
||||
this.Libp2pPeerId = libp2pPeerId
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new KeyPair with random secret key
|
||||
* Generates new KeyPair from base64 string containing the 32 byte Ed25519 private key
|
||||
* @returns - Promise with the created KeyPair
|
||||
*/
|
||||
static async fromEd25519SK(base64Key: string): Promise<KeyPair> {
|
||||
// deserialize private key from base64
|
||||
const key = base64.toByteArray(base64Key);
|
||||
return await KeyPair.fromBytes(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates new KeyPair from a 32 byte array
|
||||
* @param key - Any sequence of 32 bytes
|
||||
* @returns - Promise with the created KeyPair
|
||||
*/
|
||||
static async fromBytes(arr: Uint8Array): Promise<KeyPair> {
|
||||
// generateKeyPairFromSeed takes seed and copies it to private key as is
|
||||
const privateKey = await keys.generateKeyPairFromSeed('Ed25519', arr, 256);
|
||||
const lib2p2Pid = await PeerId.createFromPrivKey(privateKey.bytes);
|
||||
return new KeyPair(lib2p2Pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates new KeyPair with a random secret key
|
||||
* @returns - Promise with the created KeyPair
|
||||
*/
|
||||
static async randomEd25519(): Promise<KeyPair> {
|
||||
const res = new KeyPair();
|
||||
res.Libp2pPeerId = await PeerId.create({ keyType: 'Ed25519' });
|
||||
return res;
|
||||
const lib2p2Pid = await PeerId.create({ keyType: 'Ed25519' });
|
||||
return new KeyPair(lib2p2Pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns 32 byte private key
|
||||
*/
|
||||
toEd25519PrivateKey(): Uint8Array {
|
||||
return this.Libp2pPeerId.privKey.marshal().subarray(0, 32);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user