Skip to content

Commit

Permalink
Merge branch '1661-en_2' into 1662-en_7
Browse files Browse the repository at this point in the history
  • Loading branch information
lucanicoladebiasi committed Jan 28, 2025
2 parents 3227375 + 6af3507 commit 81a99dd
Show file tree
Hide file tree
Showing 20 changed files with 206 additions and 298 deletions.
2 changes: 1 addition & 1 deletion apps/sdk-vite-integration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@
"vitest": "^2.1.6",
"vitest-browser-react": "^0.0.3"
}
}
}
2 changes: 1 addition & 1 deletion docs/accounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ Through the use of mnemonics and keystore, VeChainSDK ensures secure and user-fr
```typescript { name=keystore, category=example }
// 1 - Create private key using Secp256k1

const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

// @NOTE you can use BIP 39 too!
// const words = Mnemonic.of()
Expand Down
2 changes: 1 addition & 1 deletion docs/certificates.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ It's important to note that certificates in the VeChainThor blockchain are self-
```typescript { name=sign_verify, category=example }
// 1 - Generate a private key and address for the signer

const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();
const publicKey = Secp256k1.derivePublicKey(privateKey);
const signerAddress = Address.ofPublicKey(publicKey).toString();

Expand Down
2 changes: 1 addition & 1 deletion docs/cryptography.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Secp256k1 is mainly used for generating public and private key pairs in cryptogr
```typescript { name=secp256k1, category=example }
// 1 - Generate a private key.

const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();
console.log('Private key:', Hex.of(privateKey).toString());
// Private key: ...SOME_PRIVATE_KEY...

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/accounts/keystore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { expect } from 'expect';

// 1 - Create private key using Secp256k1

const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

// @NOTE you can use BIP 39 too!
// const words = Mnemonic.of()
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/certificates/sign_verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Address, Certificate, Secp256k1 } from '@vechain/sdk-core';

// 1 - Generate a private key and address for the signer

const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();
const publicKey = Secp256k1.derivePublicKey(privateKey);
const signerAddress = Address.ofPublicKey(publicKey).toString();

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/cryptography/secp256k1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { expect } from 'expect';

// 1 - Generate a private key.

const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();
console.log('Private key:', Hex.of(privateKey).toString());
// Private key: ...SOME_PRIVATE_KEY...

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/transactions/blockref-expiration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const body: TransactionBody = {

// 3 - Create private key

const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

// 4 - Sign transaction

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/transactions/multiple-clauses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const body: TransactionBody = {
};

// Create private key
const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

// 4 - Sign transaction

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/transactions/sign-decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const body: TransactionBody = {
};

// Create private key
const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

// 4 - Sign transaction

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/transactions/tx-dependency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const txBBody: TransactionBody = {
};

// Define the senders private key
const senderPrivateKey = await Secp256k1.generatePrivateKey();
const senderPrivateKey = Secp256k1.generatePrivateKey();

// To define transaction B as dependent on transaction
// it's necessary to sign transaction A, and then get its Id
Expand Down
8 changes: 4 additions & 4 deletions docs/transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const body: TransactionBody = {
};

// Create private key
const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

// 4 - Sign transaction

Expand Down Expand Up @@ -99,7 +99,7 @@ const body: TransactionBody = {
};

// Create private key
const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

// 4 - Sign transaction

Expand Down Expand Up @@ -214,7 +214,7 @@ const body: TransactionBody = {

// 3 - Create private key

const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

// 4 - Sign transaction

Expand Down Expand Up @@ -277,7 +277,7 @@ const txBBody: TransactionBody = {
};

// Define the senders private key
const senderPrivateKey = await Secp256k1.generatePrivateKey();
const senderPrivateKey = Secp256k1.generatePrivateKey();

// To define transaction B as dependent on transaction
// it's necessary to sign transaction A, and then get its Id
Expand Down
47 changes: 15 additions & 32 deletions packages/core/src/secp256k1/Secp256k1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,41 +94,26 @@ class Secp256k1 {
}

/**
* Generates a new random private key.
* If an error occurs during generation using
* [nc_secp256k1](https://github.com/paulmillr/noble-secp256k1),
* an AES-GCM key is generated as a fallback in runtimes not supported
* by `nc_secp256k1`, if those support {@link {@link global.crypto}.
* Generates a new Secp256k1 private key using a secure random number generator.
*
* @return {Promise<Uint8Array>} The generated private key as a Uint8Array.
* @return {Uint8Array} A Uint8Array representing the generated private key.
* This encoded private key is suitable for cryptographic operations.
* @throws {InvalidSecp256k1PrivateKey} Throws an error if private key generation fails if a secure random number
* generator is not provided by the hosting operating system.
*
* @remarks Security auditable method, depends on
* * {@link global.crypto.subtle.exportKey};
* * {@link global.crypto.subtle.generateKey};
* * [nc_secp256k1.utils.randomPrivateKey](https://github.com/paulmillr/noble-secp256k1).
*/
public static async generatePrivateKey(): Promise<Uint8Array> {
public static generatePrivateKey(): Uint8Array {
try {
return nc_secp256k1.utils.randomPrivateKey();
} catch (e) {
// Generate an ECDSA key pair
const cryptoKey = await global.crypto.subtle.generateKey(
{
name: 'AES-GCM',
length: 256
},
true,
['encrypt', 'decrypt']
);

// Export the private key to raw format
const rawKey = await global.crypto.subtle.exportKey(
'raw',
cryptoKey
throw new InvalidSecp256k1PrivateKey(
'Secp256k1.generatePrivateKey',
'Private key generation failed: ensure you have a secure random number generator available at runtime.',
undefined,
e
);

// Convert the ArrayBuffer to Uint8Array
return new Uint8Array(rawKey);
}
}

Expand Down Expand Up @@ -192,20 +177,18 @@ class Secp256k1 {
* {@link {@link global.crypto} is used as fall back togenerate
* the random sequence.
*
* @param {number} [bytesLength=32] - Optional. The number of random bytes to generate.
* @param {number} [bytesLength=32] - Optional. The number of random bytes to generate, 32 by default.
* @return {Uint8Array} - A Uint8Array containing the random bytes.
*
* @remarks Security auditable method, depends on
* * {@link global.crypto.getRandomValues};
* * {@link global.crypto.getRandomValues};
* * [nh_randomBytes](https://github.com/paulmillr/noble-hashes).
*/
public static randomBytes(bytesLength?: number): Uint8Array {
public static randomBytes(bytesLength: number = 32): Uint8Array {
try {
return nh_randomBytes(bytesLength);
} catch (e) {
return global.crypto.getRandomValues(
new Uint8Array(bytesLength ?? 32)
);
return global.crypto.getRandomValues(new Uint8Array(bytesLength));
}
}

Expand Down
31 changes: 8 additions & 23 deletions packages/core/src/vcdm/Address.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { Keccak256 } from './hash/Keccak256';
import { HDKey } from '../hdkey/HDKey';
import { Hex } from './Hex';
import { HexUInt } from './HexUInt';
import { InvalidDataType, InvalidHDKey } from '@vechain/sdk-errors';
import { Keccak256 } from './hash/Keccak256';
import { Secp256k1 } from '../secp256k1/Secp256k1';
import { Txt } from './Txt';
import {
InvalidDataType,
InvalidHDKey,
InvalidSecp256k1PrivateKey
} from '@vechain/sdk-errors';

/**
* Represents a VeChain Address as unsigned integer.
Expand Down Expand Up @@ -89,29 +85,18 @@ class Address extends HexUInt {
}

/**
* Create an Address instance from the given private key.
*
* @param {Uint8Array} privateKey - The private key to convert.
*
* @param {boolean} [isCompressed=true] - The flag to indicate if the derived public key should be compressed.
* Generates an Address object from the given private key.
*
* @returns {Address} The converted address.
*
* @remarks Security auditable method, depends on
* * {@link Secp256k1.derivePublicKey}.
* @param {Uint8Array} privateKey - The private key used to derive the corresponding address.
* @return {Address} The derived Address object.
* @throws {InvalidDataType} If the provided private key is invalid or cannot derive an address.
*/
public static ofPrivateKey(
privateKey: Uint8Array,
isCompressed: boolean = true
): Address {
public static ofPrivateKey(privateKey: Uint8Array): Address {
try {
return Address.ofPublicKey(
Secp256k1.derivePublicKey(privateKey, isCompressed)
Secp256k1.derivePublicKey(privateKey, true)
);
} catch (error) {
if (error instanceof InvalidSecp256k1PrivateKey) {
throw error;
}
throw new InvalidDataType(
'Address.ofPrivateKey',
'not a valid private key',
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/vcdm/hash/Keccak256.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { Hex } from '../Hex';
import { HexUInt } from '../HexUInt';

/**
* Represents the result of an [SHA-3](https://en.wikipedia.org/wiki/SHA-3) [KECCAK 256](https://keccak.team/keccak.html) hash operation.
* Represents the result of an [KECCAK 256](https://keccak.team/keccak.html) hash operation.
*
* @extends HexUInt
*/
class Keccak256 extends HexUInt {
/**
* Generates the [KECCAK 256](https://eth-hash.readthedocs.io/en/stable/) hash of the given input.
* Generates the [KECCAK 256](https://keccak.team/keccak.html) hash of the given input.
*
* @param {bigint | number | string | Uint8Array | Hex} exp - The input value to hash.
*
Expand Down
17 changes: 11 additions & 6 deletions packages/core/tests/keystore/keystore.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { beforeEach, describe, expect, test } from '@jest/globals';
import {
InvalidDataType,
InvalidKeystore,
InvalidKeystoreParams,
InvalidSecp256k1PrivateKey,
Expand Down Expand Up @@ -31,7 +32,7 @@ import { encryptionPassword } from './fixture';
*/
test('encrypt', async () => {
// Generate a random private key
const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();
const addressFromPrivateKey =
Address.ofPrivateKey(privateKey).toString();

Expand Down Expand Up @@ -60,15 +61,19 @@ import { encryptionPassword } from './fixture';
new TextEncoder().encode('wrong private key'),
encryptionPassword
)
).rejects.toThrowError(InvalidSecp256k1PrivateKey);
).rejects.toThrowError(
experimentalCryptography
? InvalidDataType
: InvalidSecp256k1PrivateKey
);
});

/**
* Decrypt private key from keystore
*/
test('decrypt', async () => {
// Generate a random private key
const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

const expected = HexUInt.of(privateKey).toString();

Expand All @@ -93,7 +98,7 @@ import { encryptionPassword } from './fixture';
*/
test('decrypt with invalid password', async () => {
// Generate a random private key
const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

// Create keystore
const myKeystore = await keystore.encrypt(
Expand All @@ -116,7 +121,7 @@ import { encryptionPassword } from './fixture';
*/
test('decrypt invalid keystore', async () => {
// Generate a random private key
const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

// Create keystore
const myKeystore = await keystore.encrypt(
Expand Down Expand Up @@ -149,7 +154,7 @@ import { encryptionPassword } from './fixture';
*/
test('validation', async () => {
// Generate a random private key
const privateKey = await Secp256k1.generatePrivateKey();
const privateKey = Secp256k1.generatePrivateKey();

// Create keystore
const myKeystore = await keystore.encrypt(
Expand Down
Loading

0 comments on commit 81a99dd

Please sign in to comment.