-
Notifications
You must be signed in to change notification settings - Fork 200
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: bbs createKey, sign and verify (#684)
Signed-off-by: Berend Sliedrecht <[email protected]>
- Loading branch information
1 parent
cbdff28
commit 113cbb9
Showing
39 changed files
with
789 additions
and
90 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
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 |
---|---|---|
|
@@ -7,10 +7,15 @@ To start using Aries Framework JavaScript in React Native some platform specific | |
1. Follow the [React Native Setup](https://reactnative.dev/docs/environment-setup) guide to set up your environment. | ||
2. Add `@aries-framework/core`, `@aries-framework/react-native`, `react-native-fs`, and `react-native-get-random-values` to your project. | ||
|
||
## Installing dependencies | ||
|
||
```bash | ||
yarn add @aries-framework/core @aries-framework/react-native react-native-fs react-native-get-random-values | ||
``` | ||
|
||
Right now, as a patch that will later be changed, some platforms will have an "error" when installing the dependencies. This is because the BBS signatures library that we use is built for Linux x86 and MacOS x86 (and not Windows and MacOS arm). This means that it will show that it could not download the binary. | ||
This is not an error, as the library that fails is `node-bbs-signaturs` and is an optional dependency for perfomance improvements. It will fallback to a, slower, wasm build. | ||
|
||
3. Install [Libindy](https://github.com/hyperledger/indy-sdk) for iOS and Android: | ||
|
||
- [iOS](../docs/libindy/ios.md) | ||
|
@@ -81,3 +86,39 @@ try { | |
console.log(error) | ||
} | ||
``` | ||
|
||
## Using BBS Signatures | ||
|
||
When using AFJ inside the React Native environment, temporarily, a dependency for creating keys, sigining and verifying | ||
with bbs keys must be swapped. Inside your package.json the following must be added: | ||
|
||
#### yarn | ||
|
||
```diff | ||
+ "resolutions": { | ||
+ "@mattrglobal/bbs-signatures": "@animo-id/[email protected]", | ||
+ }, | ||
"dependencies": { | ||
... | ||
+ "@animo-id/react-native-bbs-signatures": "0.1.0", | ||
} | ||
``` | ||
|
||
#### npm | ||
|
||
```diff | ||
+ "overrides": { | ||
+ "@mattrglobal/bbs-signatures": "@animo-id/[email protected]", | ||
+ }, | ||
"dependencies": { | ||
... | ||
+ "@animo-id/react-native-bbs-signatures": "0.1.0", | ||
} | ||
``` | ||
|
||
The resolution field says that any instance of `@mattrglobal/bbs-signatures` in any child dependency must be swapped | ||
with `react-native-bbs-signatures`. | ||
|
||
The added dependency is required for autolinking and should be the same as the one used in the resolution. | ||
|
||
[React Native Bbs Signature](https://github.com/animo/react-native-bbs-signatures) has some quirks with setting it up correctly. If any errors occur while using this library, please refer to their README for the installation guide. |
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,151 @@ | ||
import type { CreateKeyOptions } from '../wallet' | ||
import type { BlsKeyPair as _BlsKeyPair } from '@mattrglobal/bbs-signatures' | ||
|
||
import { | ||
bls12381toBbs, | ||
generateBls12381G2KeyPair, | ||
generateBls12381G1KeyPair, | ||
sign, | ||
verify, | ||
} from '@mattrglobal/bbs-signatures' | ||
|
||
import { TypedArrayEncoder } from '../utils/TypedArrayEncoder' | ||
import { Buffer } from '../utils/buffer' | ||
import { WalletError } from '../wallet/error' | ||
|
||
import { KeyType } from './KeyType' | ||
|
||
export interface BlsKeyPair { | ||
publicKeyBase58: string | ||
privateKeyBase58: string | ||
keyType: Extract<KeyType, KeyType.Bls12381g1 | KeyType.Bls12381g2 | KeyType.Bls12381g1g2> | ||
} | ||
|
||
interface BbsCreateKeyOptions extends CreateKeyOptions { | ||
keyType: Extract<KeyType, KeyType.Bls12381g1 | KeyType.Bls12381g2> | ||
} | ||
|
||
interface BbsSignOptions { | ||
messages: Buffer | Buffer[] | ||
publicKey: Buffer | ||
privateKey: Buffer | ||
} | ||
|
||
interface BbsVerifyOptions { | ||
publicKey: Buffer | ||
signature: Buffer | ||
messages: Buffer | Buffer[] | ||
} | ||
|
||
export class BbsService { | ||
/** | ||
* Create an instance of a Key class for the following key types: | ||
* - Bls12381g1 | ||
* - Bls12381g2 | ||
* | ||
* @param keyType KeyType The type of key to be created (see above for the accepted types) | ||
* | ||
* @returns A Key class with the public key and key type | ||
* | ||
* @throws {WalletError} When a key could not be created | ||
* @throws {WalletError} When the method is called with an invalid keytype | ||
*/ | ||
public static async createKey({ keyType, seed }: BbsCreateKeyOptions): Promise<BlsKeyPair> { | ||
// Generate bytes from the seed as required by the bbs-signatures libraries | ||
const seedBytes = seed ? TypedArrayEncoder.fromString(seed) : undefined | ||
|
||
// Temporary keypair holder | ||
let blsKeyPair: Required<_BlsKeyPair> | ||
|
||
switch (keyType) { | ||
case KeyType.Bls12381g1: | ||
// Generate a bls12-381G1 keypair | ||
blsKeyPair = await generateBls12381G1KeyPair(seedBytes) | ||
break | ||
case KeyType.Bls12381g2: | ||
// Generate a bls12-381G2 keypair | ||
blsKeyPair = await generateBls12381G2KeyPair(seedBytes) | ||
break | ||
default: | ||
// additional check. Should never be hit as this function will only be called from a place where | ||
// a key type check already happened. | ||
throw new WalletError(`Cannot create key with the BbsService for key type: ${keyType}`) | ||
} | ||
|
||
return { | ||
keyType, | ||
publicKeyBase58: TypedArrayEncoder.toBase58(blsKeyPair.publicKey), | ||
privateKeyBase58: TypedArrayEncoder.toBase58(blsKeyPair.secretKey), | ||
} | ||
} | ||
|
||
/** | ||
* Sign an arbitrary amount of messages, in byte form, with a keypair | ||
* | ||
* @param messages Buffer[] List of messages in Buffer form | ||
* @param publicKey Buffer Publickey required for the signing process | ||
* @param privateKey Buffer PrivateKey required for the signing process | ||
* | ||
* @returns A Buffer containing the signature of the messages | ||
* | ||
* @throws {WalletError} When there are no supplied messages | ||
*/ | ||
public static async sign({ messages, publicKey, privateKey }: BbsSignOptions): Promise<Buffer> { | ||
if (messages.length === 0) throw new WalletError('Unable to create a signature without any messages') | ||
// Check if it is a single message or list and if it is a single message convert it to a list | ||
const normalizedMessages = (TypedArrayEncoder.isTypedArray(messages) ? [messages as Buffer] : messages) as Buffer[] | ||
|
||
// Get the Uint8Array variant of all the messages | ||
const messageBuffers = normalizedMessages.map((m) => Uint8Array.from(m)) | ||
|
||
const bbsKeyPair = await bls12381toBbs({ | ||
keyPair: { publicKey: Uint8Array.from(publicKey), secretKey: Uint8Array.from(privateKey) }, | ||
messageCount: normalizedMessages.length, | ||
}) | ||
|
||
// Sign the messages via the keyPair | ||
const signature = await sign({ | ||
keyPair: bbsKeyPair, | ||
messages: messageBuffers, | ||
}) | ||
|
||
// Convert the Uint8Array signature to a Buffer type | ||
return Buffer.from(signature) | ||
} | ||
|
||
/** | ||
* Verify an arbitrary amount of messages with their signature created with their key pair | ||
* | ||
* @param publicKey Buffer The public key used to sign the messages | ||
* @param messages Buffer[] The messages that have to be verified if they are signed | ||
* @param signature Buffer The signature that has to be verified if it was created with the messages and public key | ||
* | ||
* @returns A boolean whether the signature is create with the public key over the messages | ||
* | ||
* @throws {WalletError} When the message list is empty | ||
* @throws {WalletError} When the verification process failed | ||
*/ | ||
public static async verify({ signature, messages, publicKey }: BbsVerifyOptions): Promise<boolean> { | ||
if (messages.length === 0) throw new WalletError('Unable to create a signature without any messages') | ||
// Check if it is a single message or list and if it is a single message convert it to a list | ||
const normalizedMessages = (TypedArrayEncoder.isTypedArray(messages) ? [messages as Buffer] : messages) as Buffer[] | ||
|
||
// Get the Uint8Array variant of all the messages | ||
const messageBuffers = normalizedMessages.map((m) => Uint8Array.from(m)) | ||
|
||
const bbsKeyPair = await bls12381toBbs({ | ||
keyPair: { publicKey: Uint8Array.from(publicKey) }, | ||
messageCount: normalizedMessages.length, | ||
}) | ||
|
||
// Verify the signature against the messages with their public key | ||
const { verified, error } = await verify({ signature, messages: messageBuffers, publicKey: bbsKeyPair.publicKey }) | ||
|
||
// If the messages could not be verified and an error occured | ||
if (!verified && error) { | ||
throw new WalletError(`Could not verify the signature against the messages: ${error}`) | ||
} | ||
|
||
return verified | ||
} | ||
} |
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
6 changes: 3 additions & 3 deletions
6
packages/core/src/modules/dids/domain/Key.ts → packages/core/src/crypto/Key.ts
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 +1,2 @@ | ||
export { KeyType } from './KeyType' | ||
export { Key } from './Key' |
2 changes: 1 addition & 1 deletion
2
...les/dids/domain/key-type/multiCodecKey.ts → packages/core/src/crypto/multiCodecKey.ts
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
4 changes: 2 additions & 2 deletions
4
packages/core/src/modules/dids/domain/key-type/__tests__/bls12381g1.test.ts
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.