Skip to content

Commit

Permalink
Merge pull request #326 from casper-ecosystem/fix/ed25519-private-length
Browse files Browse the repository at this point in the history
Support 64 bytes Ed25519 private key
  • Loading branch information
hoffmannjan authored Jul 5, 2023
2 parents 53d7d9a + a1f187b commit cb17347
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-casper-client-sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
run: npm install

- name: Audits
run: npm audit
run: npm audit --omit=dev

- name: Lints
run: npm run lint:ci
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to casper-js-sdk.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 2.13.3

### Fixed

- Fixed to support 64 bytes Ed25519 private key generated using v2.10

## 2.13.2

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "casper-js-sdk",
"version": "2.13.2",
"version": "2.13.3",
"license": "Apache 2.0",
"description": "SDK to interact with the Casper blockchain",
"homepage": "https://github.com/casper-ecosystem/casper-js-sdk#README.md",
Expand Down
60 changes: 60 additions & 0 deletions src/lib/Keys.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { expect } from 'chai';
import sinon from 'sinon';

import { decodeBase16, decodeBase64 } from './Conversions';
import { Ed25519, Secp256K1 } from './Keys';
Expand Down Expand Up @@ -33,6 +34,65 @@ describe('Ed25519', () => {
const key3 = Ed25519.readBase64WithPEM(keyWithCRLF);
expect(key3).to.deep.eq(key1);
});

it('should parse old 64 bytes private key', () => {
// In v2.10 we used https://www.npmjs.com/package/tweetnacl-ts#sign_keypair which private key length is 64 bytes,
// From v2.13 migrated to noble scope libraries which private key length is 32 bytes [correct implementation]
// new version should support old format

// prettier-ignore
const privateKey = new Uint8Array([
92, 85, 34, 21, 229, 142, 168,
76, 221, 116, 56, 193, 153, 129,
32, 198, 125, 90, 231, 143, 220,
220, 158, 37, 196, 198, 34, 177,
100, 221, 229, 228
]);
// prettier-ignore
const publicKey = new Uint8Array([
225, 123, 67, 141, 123, 40, 119, 138,
213, 235, 175, 59, 71, 169, 39, 235,
243, 228, 113, 203, 25, 9, 125, 64,
97, 165, 224, 86, 97, 251, 1, 91
]);

const privateKeyPEM =
'-----BEGIN PRIVATE KEY-----\n' +
'MC4CAQAwBQYDK2VwBCIEIFxVIhXljqhM3XQ4wZmBIMZ9WueP3NyeJcTGIrFk3eXk=\n' +
'-----END PRIVATE KEY-----\n';

const publicKeyPEM =
'-----BEGIN PUBLIC KEY-----\n' +
'MCowBQYDK2VwAyEA4XtDjXsod4rV6687R6kn6/PkccsZCX1AYaXgVmH7AVs=\n' +
'-----END PUBLIC KEY-----\n';

// prettier-ignore
const oldPrivateKey = new Uint8Array([
92, 85, 34, 21, 229, 142, 168, 76, 221, 116, 56,
193, 153, 129, 32, 198, 125, 90, 231, 143, 220, 220,
158, 37, 196, 198, 34, 177, 100, 221, 229, 228, 225,
123, 67, 141, 123, 40, 119, 138, 213, 235, 175, 59,
71, 169, 39, 235, 243, 228, 113, 203, 25, 9, 125,
64, 97, 165, 224, 86, 97, 251, 1, 91
])

const keyPair = Ed25519.parseKeyPair(publicKey, privateKey);
const keyPairFromPEM = Ed25519.parseKeyPair(
Ed25519.parsePublicKey(Ed25519.readBase64WithPEM(publicKeyPEM)),
Ed25519.parsePrivateKey(Ed25519.readBase64WithPEM(privateKeyPEM))
);

const spy = sinon.spy(console, 'warn');

const oldKeyPair = new Ed25519({ publicKey, secretKey: oldPrivateKey });

expect(keyPair.privateKey).deep.equal(keyPairFromPEM.privateKey);
expect(oldKeyPair.privateKey).deep.equal(keyPairFromPEM.privateKey);

expect(spy.calledOnce).true;

spy.restore();
});
});

describe('Secp256K1', () => {
Expand Down
20 changes: 14 additions & 6 deletions src/lib/Keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const ED25519_PEM_PUBLIC_KEY_TAG = 'PUBLIC KEY';

export interface SignKeyPair {
publicKey: Uint8Array; // Array with 32-byte public key
secretKey: Uint8Array; // Array with 64-byte secret key
secretKey: Uint8Array; // Array with 32-byte secret key
}

export const getKeysFromHexPrivKey = (
Expand Down Expand Up @@ -206,16 +206,24 @@ export class Ed25519 extends AsymmetricKey {
/**
* Constructs a new Ed25519 object from a `SignKeyPair`
* @param {SignKeyPair} keyPair An object containing the keys "publicKey" and "secretKey" with corresponding `ByteArray` values
* @see [SignKeyPair](https://www.npmjs.com/package/tweetnacl-ts#sign_keypair)
*/
constructor(keyPair: SignKeyPair) {
super(keyPair.publicKey, keyPair.secretKey, SignatureAlgorithm.Ed25519);
if (keyPair.secretKey.length != 32) {
console.warn(
`You're using private key from old version, please use newly formatted key with 32 bytes length.`
);
}

super(
keyPair.publicKey,
Ed25519.parsePrivateKey(keyPair.secretKey),
SignatureAlgorithm.Ed25519
);
}

/**
* Generates a new Ed25519 key pair
* @returns A new `Ed25519` object
* @see [nacl.sign_keyPair](https://www.npmjs.com/package/tweetnacl-ts#sign_keypair)
*/
public static new() {
const privateKey = ed25519.utils.randomPrivateKey();
Expand Down Expand Up @@ -265,12 +273,12 @@ export class Ed25519 extends AsymmetricKey {
* Construct a keypair from a public key and corresponding private key
* @param {Uint8Array} publicKey The public key of an Ed25519 account
* @param {Uint8Array} privateKey The private key of the same Ed25519 account
* @returns A new `AsymmetricKey` keypair
* @returns A new `Ed25519` keypair
*/
public static parseKeyPair(
publicKey: Uint8Array,
privateKey: Uint8Array
): AsymmetricKey {
): Ed25519 {
const keyPair = new Ed25519({
publicKey: Ed25519.parsePublicKey(publicKey),
secretKey: Ed25519.parsePrivateKey(privateKey)
Expand Down

0 comments on commit cb17347

Please sign in to comment.