Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

582 xp fix linter address #585

Merged
merged 3 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions packages/massa-web3/src/experimental/basicElements/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Base58 from '../crypto/base58'
import Serializer from '../crypto/interfaces/serializer'
import { Version, Versioner } from '../crypto/interfaces/versioner'
import VarintVersioner from '../crypto/varintVersioner'
import { FIRST } from '../utils/noMagic'
import { PublicKey } from './keys'
import varint from 'varint'

Expand Down Expand Up @@ -38,7 +39,7 @@ function getVersion(data: string | Uint8Array): Version {
*/
function getPrefix(str: string): string {
const expected = [ADDRESS_USER_PREFIX, ADDRESS_CONTRACT_PREFIX]
for (let prefix of expected) {
for (const prefix of expected) {
if (str.startsWith(prefix)) {
return prefix
}
Expand Down Expand Up @@ -230,17 +231,25 @@ export class Address {
*/
static extractFromBuffer(
data: Uint8Array,
offset = 0
offset = FIRST
): { data: Uint8Array; length: number } {
// addr type
varint.decode(data, offset)
let addrByteLen = varint.decode.bytes
const typeLen = varint.decode.bytes
if (typeLen === undefined) {
throw new Error('invalid address: type not found.')
}

// version
varint.decode(data, offset + addrByteLen)
addrByteLen += varint.decode.bytes
varint.decode(data, offset + typeLen)
const versionLen = varint.decode.bytes
if (versionLen === undefined) {
throw new Error('invalid address: version not found.')
}

const addrLen = typeLen + versionLen + UNDERLYING_HASH_LEN

addrByteLen += UNDERLYING_HASH_LEN
const extractedData = data.slice(offset, offset + addrByteLen)
return { data: extractedData, length: addrByteLen }
const extractedData = data.slice(offset, offset + addrLen)
return { data: extractedData, length: addrLen }
}
}
2 changes: 2 additions & 0 deletions packages/massa-web3/src/experimental/crypto/base58.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import Serializer from './interfaces/serializer'
* Base58 implementation of the Serializer interface.
*/
export default class Base58 implements Serializer {
// eslint-disable-next-line class-methods-use-this -- Expected by the interface.
serialize(data: Uint8Array): string {
return encode(data)
}

// eslint-disable-next-line class-methods-use-this -- Expected by the interface.
deserialize(data: string): Uint8Array {
return decode(data)
}
Expand Down
1 change: 1 addition & 0 deletions packages/massa-web3/src/experimental/crypto/blake3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Hasher from './interfaces/hasher'
* Blake3 implementation of the Hasher interface.
*/
export default class Blake3 implements Hasher {
// eslint-disable-next-line class-methods-use-this -- Expected by the interface.
hash(data: Buffer | Uint8Array | string): Uint8Array {
return hashBlake3(data)
}
Expand Down
96 changes: 54 additions & 42 deletions packages/massa-web3/src/experimental/crypto/cross-browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
* If you extend this module, please check that the functions are working in both Node.js and the browser.
*/

import { FIRST } from '../utils/noMagic'

const KEY_SIZE_BYTES = 32
const IV_SIZE_BYTES = 12
const AUTH_TAG_SIZE_BYTES = 16

const U8_SIZE_BITS = 8

function isNode(): boolean {
// inspired from secure-random.js
// we check for process.pid to prevent browserify from tricking us
Expand Down Expand Up @@ -64,15 +72,15 @@ async function pbkdf2Browser(
hash: { name: hash },
},
keyMaterial,
{ name: 'AES-GCM', length: keyLength * 8 },
{ name: 'AES-GCM', length: keyLength * U8_SIZE_BITS },
false,
['encrypt', 'decrypt']
)

return Buffer.from(crypto.subtle.exportKey('raw', derivedKey))
}

export interface PBKDF2Options {
export type PBKDF2Options = {
iterations: number
keyLength: number
hash: string
Expand All @@ -94,9 +102,9 @@ export async function pbkdf2(
): Promise<Uint8Array> {
if (isNode()) {
return pbkdf2Node(password, salt, opts)
} else {
return pbkdf2Browser(password, salt, opts)
}

return pbkdf2Browser(password, salt, opts)
}

/**
Expand All @@ -116,11 +124,11 @@ export async function aesGCMEncrypt(
key: Uint8Array,
iv: Uint8Array
): Promise<Uint8Array> {
if (key.length !== 32) {
throw new Error('key must be 32 bytes')
if (key.length !== KEY_SIZE_BYTES) {
throw new Error(`key must be ${KEY_SIZE_BYTES} bytes`)
}
if (iv.length !== 12) {
throw new Error('iv must be 12 bytes')
if (iv.length !== IV_SIZE_BYTES) {
throw new Error(`iv must be ${IV_SIZE_BYTES} bytes`)
}
if (isNode()) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
Expand All @@ -132,21 +140,21 @@ export async function aesGCMEncrypt(
cipher.getAuthTag(),
])
return encrypted
} else {
const keyData = await window.crypto.subtle.importKey(
'raw',
key,
{ name: 'AES-GCM' },
false,
['encrypt']
)
const encrypted = await window.crypto.subtle.encrypt(
{ name: 'AES-GCM', iv: iv },
keyData,
data
)
return Buffer.from(encrypted)
}

const keyData = await window.crypto.subtle.importKey(
'raw',
key,
{ name: 'AES-GCM' },
false,
['encrypt']
)
const encrypted = await window.crypto.subtle.encrypt(
{ name: 'AES-GCM', iv: iv },
keyData,
data
)
return Buffer.from(encrypted)
}

/**
Expand All @@ -169,36 +177,40 @@ export async function aesGCMDecrypt(
key: Uint8Array,
iv: Uint8Array
): Promise<Uint8Array> {
if (key.length !== 32) {
throw new Error('key must be 32 bytes')
if (key.length !== KEY_SIZE_BYTES) {
throw new Error(`key must be ${KEY_SIZE_BYTES} bytes`)
}
if (iv.length !== 12) {
throw new Error('iv must be 12 bytes')
if (iv.length !== IV_SIZE_BYTES) {
throw new Error(`iv must be ${IV_SIZE_BYTES} bytes`)
}
if (isNode()) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const crypto = require('crypto')
encryptedData = Buffer.from(encryptedData)
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv)
decipher.setAuthTag(encryptedData.slice(encryptedData.length - 16))
decipher.setAuthTag(
encryptedData.slice(encryptedData.length - AUTH_TAG_SIZE_BYTES)
)
const decrypted = Buffer.concat([
decipher.update(encryptedData.slice(0, encryptedData.length - 16)),
decipher.update(
encryptedData.slice(FIRST, encryptedData.length - AUTH_TAG_SIZE_BYTES)
),
decipher.final(),
])
return decrypted
} else {
const keyData = await window.crypto.subtle.importKey(
'raw',
key,
{ name: 'AES-GCM' },
false,
['decrypt']
)
const decrypted = await window.crypto.subtle.decrypt(
{ name: 'AES-GCM', iv: iv },
keyData,
encryptedData
)
return Buffer.from(decrypted)
}

const keyData = await window.crypto.subtle.importKey(
'raw',
key,
{ name: 'AES-GCM' },
false,
['decrypt']
)
const decrypted = await window.crypto.subtle.decrypt(
{ name: 'AES-GCM', iv: iv },
keyData,
encryptedData
)
return Buffer.from(decrypted)
}
4 changes: 4 additions & 0 deletions packages/massa-web3/src/experimental/crypto/ed25519.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@ import Signer from './interfaces/signer'
* Ed25519 implementation of the Signer interface.
*/
export default class Ed25519 implements Signer {
// eslint-disable-next-line class-methods-use-this -- Expected by the interface.
generatePrivateKey(): Uint8Array {
return ed.utils.randomPrivateKey()
}

// eslint-disable-next-line class-methods-use-this -- Expected by the interface.
async getPublicKey(privateKey: Uint8Array): Promise<Uint8Array> {
return ed.getPublicKey(privateKey)
}

// eslint-disable-next-line class-methods-use-this -- Expected by the interface.
async sign(privateKey: Uint8Array, data: Uint8Array): Promise<Uint8Array> {
return ed.sign(data, privateKey)
}

// eslint-disable-next-line class-methods-use-this -- Expected by the interface.
async verify(
publicKey: Uint8Array,
data: Uint8Array,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- True interface.
export default interface Hasher {
hash(data: Buffer | Uint8Array | string): Uint8Array
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- True interface.
export default interface Sealer {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
seal(data: Uint8Array): Promise<any>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- True interface.
export default interface Serializer {
serialize(data: Uint8Array): string
deserialize(data: string): Uint8Array
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- True interface.
export default interface Signer {
generatePrivateKey(): Uint8Array
getPublicKey(privateKey: Uint8Array): Promise<Uint8Array>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- True interface.
export interface Versioner {
attach(version: Version, data: Uint8Array): Uint8Array
extract(data: Uint8Array): { version: Version; data: Uint8Array }
Expand Down
35 changes: 14 additions & 21 deletions packages/massa-web3/src/experimental/crypto/passwordSeal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@
pbkdf2,
} from './cross-browser'

const KEY_SIZE_BYTES = 32
const NONCE_SIZE_BYTES = 12
const SALT_SIZE_BYTES = 16
const OWASP_ITERATIONS = 600000

function createKey(password: string, salt: Buffer): Promise<Uint8Array> {
const opts: PBKDF2Options = {
iterations: 600000,
keyLength: 32,
iterations: OWASP_ITERATIONS,
keyLength: KEY_SIZE_BYTES,
hash: 'SHA-256',
}
return pbkdf2(password, salt, opts)
Expand All @@ -26,31 +31,19 @@
public nonce: Uint8Array

constructor(password: string, salt?: Uint8Array, nonce?: Uint8Array) {
if (salt === undefined) {
this.salt = randomUint8Array(16)
} else if (salt.length !== 16) {
throw new Error('Salt must be 16 bytes')
} else {
this.salt = salt
}

if (nonce === undefined) {
this.nonce = randomUint8Array(12)
} else if (nonce.length !== 12) {
throw new Error('Nonce must be 12 bytes')
} else {
this.nonce = nonce
}
this.salt = salt ?? randomUint8Array(SALT_SIZE_BYTES)

Check warning on line 34 in packages/massa-web3/src/experimental/crypto/passwordSeal.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
this.nonce = nonce ?? randomUint8Array(NONCE_SIZE_BYTES)

Check warning on line 35 in packages/massa-web3/src/experimental/crypto/passwordSeal.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
this.validate()

this.password = password
}

private validate(): void {
if (!this.salt || this.salt.length !== 16) {
throw new Error('Salt must be 16 bytes')
if (!this.salt || this.salt.length !== SALT_SIZE_BYTES) {
throw new Error(`Salt must be ${SALT_SIZE_BYTES} bytes`)

Check warning on line 43 in packages/massa-web3/src/experimental/crypto/passwordSeal.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}

Check warning on line 44 in packages/massa-web3/src/experimental/crypto/passwordSeal.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
if (!this.nonce || this.nonce.length !== 12) {
throw new Error('Nonce must be 12 bytes')
if (!this.nonce || this.nonce.length !== NONCE_SIZE_BYTES) {
throw new Error(`Nonce must be ${NONCE_SIZE_BYTES} bytes`)

Check warning on line 46 in packages/massa-web3/src/experimental/crypto/passwordSeal.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}

Check warning on line 47 in packages/massa-web3/src/experimental/crypto/passwordSeal.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default class VarintVersioner implements Versioner {
*
* @returns The versioned data.
*/
// eslint-disable-next-line class-methods-use-this -- Expected by the interface.
attach(version: Version, data: Uint8Array): Uint8Array {
const versionArray = varint.encode(version)
return new Uint8Array([...versionArray, ...data])
Expand All @@ -25,6 +26,7 @@ export default class VarintVersioner implements Versioner {
*
* @returns The version and the data.
*/
// eslint-disable-next-line class-methods-use-this -- Expected by the interface.
extract(data: Uint8Array): { version: Version; data: Uint8Array } {
const version = varint.decode(data)
return { data: data.slice(varint.decode.bytes), version }
Expand Down
2 changes: 2 additions & 0 deletions packages/massa-web3/src/experimental/utils/noMagic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const FIRST = 0
export const ONE = 1
Loading