Skip to content

Commit

Permalink
Merge pull request #97 from casper-ecosystem/sign-msg
Browse files Browse the repository at this point in the history
SignMessage implemented
  • Loading branch information
hoffmannjan authored Aug 13, 2021
2 parents 01c4433 + 5cb2afe commit 6ca3d2b
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 1 deletion.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ 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.5.0

### Added

- `signMessage` - added method to sign arbitrary string message
- `verifyMessageSignature` - added method to verify signature of arbitrary string message

## 2.4.1

### Fixed
Expand Down
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.4.1",
"version": "2.5.0",
"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
47 changes: 47 additions & 0 deletions src/lib/SignedMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as nacl from 'tweetnacl-ts';
import * as secp256k1 from 'ethereum-cryptography/secp256k1';
import { sha256 } from 'ethereum-cryptography/sha256';

import { CLPublicKey } from './CLValue/';
import { AsymmetricKey } from './Keys';

/**
* Method for signing string message.
* @param key AsymmetricKey used to sign the message
* @param message Message that will be signed
* @return Uint8Array Signature in byte format
*/
export const signMessage = (
key: AsymmetricKey,
message: string
): Uint8Array => {
const messageWithHeader = Buffer.from(`Casper Message:\n${message}`);
return key.sign(messageWithHeader);
};

/**
* Method to verify signature
* @param key Public key of private key used to signed.
* @param message Message that was signed
* @param signature Signature in byte format
* @return boolean Verification result
*/
export const verifyMessageSignature = (
key: CLPublicKey,
message: string,
signature: Uint8Array
): boolean => {
const messageWithHeader = Buffer.from(`Casper Message:\n${message}`);
if (key.isEd25519()) {
return nacl.sign_detached_verify(messageWithHeader, signature, key.value());
}
if (key.isSecp256K1()) {
return secp256k1.ecdsaVerify(
signature,
sha256(messageWithHeader),
key.value()
);
}

throw new Error('Unsupported algorithm.');
};
1 change: 1 addition & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ import * as Signer from './Signer';
export * from './CLValue';
export * from './RuntimeArgs';
export * from './CasperClient';
export * from './SignedMessage';

export { Contracts, Keys, Serialization, DeployUtil, Signer };
31 changes: 31 additions & 0 deletions test/lib/SignedMessage.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { expect } from 'chai';
import { Ed25519, Secp256K1 } from '../../src/lib/Keys';
import { signMessage, verifyMessageSignature } from '../../src/index';

describe('SignedMessage', () => {
it('Should generate proper signed message and validate it (Ed25519)', () => {
const signKeyPair = Ed25519.new();
const exampleMessage = "Hello World!";
const wrongMessage = "!Hello World";

const signature = signMessage(signKeyPair, exampleMessage);
const valid = verifyMessageSignature(signKeyPair.publicKey, exampleMessage, signature);
const invalid = verifyMessageSignature(signKeyPair.publicKey, wrongMessage, signature);

expect(valid).to.be.eq(true);
expect(invalid).to.be.eq(false);
});

it('Should generate proper signed message and validate it (Secp256K1)', () => {
const signKeyPair = Secp256K1.new();
const exampleMessage = "Hello World!";
const wrongMessage = "!Hello World";

const signature = signMessage(signKeyPair, exampleMessage);
const valid = verifyMessageSignature(signKeyPair.publicKey, exampleMessage, signature);
const invalid = verifyMessageSignature(signKeyPair.publicKey, wrongMessage, signature);

expect(valid).to.be.eq(true);
expect(invalid).to.be.eq(false);
});
});

0 comments on commit 6ca3d2b

Please sign in to comment.