A fundamental building block of Ethereum is the underlying cryptographic primitives.
<src>ProgressCallback⇒ (percent: number) => void A callback during long-running operations to update any UI or provide programatic access to the progress.
The percent is a value between 0 and 1.
<src>SignatureLike⇒ Signature | string | { r: string , s: string , v: BigNumberish , yParity?: 0 | 1 , yParityAndS?: string } | { r: string , s?: string , v?: number , yParity?: 0 | 1 , yParityAndS: string } | { r: string , s: string , v?: BigNumberish , yParity: 0 | 1 , yParityAndS?: string } Cryptographic hashing functions
Compute the cryptographic KECCAK256 hash of data.
The data must be a data representation, to compute the hash of UTF-8 data use the id function.
keccak256("0x")
// '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
keccak256("0x1337")
// '0x2636a8beb2c41b8ccafa9a55a5a5e333892a83b491df3a67d2768946a9f9c6dc'
keccak256(new Uint8Array([ 0x13, 0x37 ]))
// '0x2636a8beb2c41b8ccafa9a55a5a5e333892a83b491df3a67d2768946a9f9c6dc'
keccak256("Hello World")
// Error("invalid BytesLike value", {
// code: "INVALID_ARGUMENT"
// argument: "data"
// value: "Hello World"
// })
Compute the cryptographic RIPEMD-160 hash of data.
ripemd160("0x")
// '0x9c1185a5c5e9fc54612808977ee8f548b2258d31'
ripemd160("0x1337")
// '0x224d2bd5251d8f9faa114eb0826e371d1236fda1'
ripemd160(new Uint8Array([ 0x13, 0x37 ]))
// '0x224d2bd5251d8f9faa114eb0826e371d1236fda1'
Compute the cryptographic SHA2-256 hash of data.
sha256("0x")
// '0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
sha256("0x1337")
// '0x158760c856e5ea1ba97e2e2a456736c4bf30d964559afa6d748cf05694a636ff'
sha256(new Uint8Array([ 0x13, 0x37 ]))
// '0x158760c856e5ea1ba97e2e2a456736c4bf30d964559afa6d748cf05694a636ff'
Compute the cryptographic SHA2-512 hash of data.
sha512("0x")
// '0xcf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
sha512("0x1337")
// '0x55ccb35e52b39adac42b68304bf33ff7ecb854f09b2e761e234061482e98e45b4e68de2756bcc7b7099d7dd178f04dafa229d403b90bf8884eedea3806d4642b'
sha512(new Uint8Array([ 0x13, 0x37 ]))
// '0x55ccb35e52b39adac42b68304bf33ff7ecb854f09b2e761e234061482e98e45b4e68de2756bcc7b7099d7dd178f04dafa229d403b90bf8884eedea3806d4642b'
An HMAC enables verification that a given key was used to authenticate a payload.
See: link-wiki-hmac
Return the HMAC for data using the key key with the underlying algo used for compression.
key = id("some-secret")
computeHmac("sha256", key, "0x1337")
// '0xbc985612171f71b89c7561c593f2cea20038d3f38f710b2516e405085d7c0c79'
computeHmac("sha256", key, toUtf8Bytes("Hello World"))
// '0xd0404ef8fae0d7f18a54a0ddfad8b81afa9e4cdab872a1dc36628c4397fd8201'
A Password-Based Key-Derivation Function is designed to create a sequence of bytes suitible as a key from a human-rememberable password.
<src>pbkdf2(password: BytesLike, salt: BytesLike, iterations: number, keylen: number, algo: "sha256" | "sha512")⇒ string Return the PBKDF2 for keylen bytes for password using the salt and using iterations of algo.
This PBKDF is outdated and should not be used in new projects, but is required to decrypt older files.
password = "hello"
passwordBytes = toUtf8Bytes(password, "NFKC")
salt = id("some-salt")
pbkdf2(passwordBytes, salt, 1024, 16, "sha256")
// '0x226addf5b6d87544337e9733b99ceb9d'
The scrypt PBKDF uses a memory and cpu hard method of derivation to increase the resource cost to brute-force a password for a given key.
This means this algorithm is intentionally slow, and can be tuned to become slower. As computation and memory speed improve over time, increasing the difficulty maintains the cost of an attacker.
For example, if a target time of 5 seconds is used, a legitimate user which knows their password requires only 5 seconds to unlock their account. A 6 character password has 68 billion possibilities, which would require an attacker to invest over 10,000 years of CPU time. This is of course a crude example (as password generally aren't random), but demonstrates to value of imposing large costs to decryption.
For this reason, if building a UI which involved decrypting or encrypting datsa using scrypt, it is recommended to use a ProgressCallback (as event short periods can seem lik an eternity if the UI freezes). Including the phrase "decrypting" in the UI can also help, assuring the user their waiting is for a good reason.
password = "hello"
passwordBytes = toUtf8Bytes(password, "NFKC")
salt = id("some-salt")
scrypt(passwordBytes, salt, 1024, 8, 1, 16)
// Promise<'0x3982633256a26ab2e62efa0621d1a5c0'>
Provides a synchronous variant of scrypt.
This will completely lock up and freeze the UI in a browser and will prevent any event loop from progressing. For this reason, it is preferred to use the async variant.
password = "hello"
passwordBytes = toUtf8Bytes(password, "NFKC")
salt = id("some-salt")
scryptSync(passwordBytes, salt, 1024, 8, 1, 16)
// '0x3982633256a26ab2e62efa0621d1a5c0'
A Cryptographically Secure Random Value is one that has been generated with additional care take to prevent side-channels from allowing others to detect it and prevent others from through coincidence generate the same values.
<src>randomBytes(length: number)⇒ Uint8Array Return length bytes of cryptographically secure random data.
randomBytes(8)
// Uint8Array(8) [
// 122, 197, 123,
// 228, 254, 209,
// 45, 213
// ]
<src>signature.compactSerialized⇒ stringread-only <src>signature.legacyChainId⇒ null | bigintread-only The chain ID for EIP-155 legacy transactions. For non-legacy transactions, this value is null.
<src>signature.networkV⇒ null | bigintread-only The EIP-155 v for legacy transactions. For non-legacy transactions, this value is null.
The r value for a signautre.
This represents the x coordinate of a "reference" or challenge point, from which the y can be computed.
The s value for a signature.
<src>signature.serialized⇒ stringread-only The serialized representation.
<src>signature.v⇒ 27 | 28 The v value for a signature.
Since a given x value for r has two possible values for its correspondin y, the v indicates which of the two y values to use.
It is normalized to the values 27 or 28 for legacy purposes.
<src>signature.yParity⇒ 0 | 1read-only The yParity for the signature.
See v for more details on how this value is used.
<src>signature.yParityAndS⇒ stringread-only The EIP-2098 compact representation of the yParity and s compacted into a single bytes32.
Creates a new Signature.
If no sig is provided, a new Signature is created with default values.
If sig is a string, it is parsed.
<src>signature.toJSON()⇒ any Returns a representation that is compatible with JSON.stringify.
Compute the chain ID from the v in a legacy EIP-155 transactions.
Signature.getChainId(45)
// 5n
Signature.getChainId(46)
// 5n
Compute the v for a chain ID for a legacy EIP-155 transactions.
Legacy transactions which use EIP-155 hijack the v property to include the chain ID.
Signature.getChainIdV(5, 27)
// 45n
Signature.getChainIdV(5, 28)
// 46n
Compute the normalized legacy transaction v from a yParirty, a legacy transaction v or a legacy EIP-155 transaction.
Signature.getNormalizedV(0)
// 27
Signature.getNormalizedV(27)
// 27
Signature.getNormalizedV(46)
// 28
Signature.getNormalizedV(5)
// Error("invalid v", {
// code: "INVALID_ARGUMENT"
// argument: "v"
// value: 5
// })
A SigningKey provides high-level access to the elliptic curve cryptography (ECC) operations and key management.
<src>signingKey.compressedPublicKey⇒ stringread-only The compressed public key.
This will always begin with either the prefix 0x02 or 0x03 and be 68 characters long (the 0x prefix and 33 hexadecimal nibbles)
<src>signingKey.privateKey⇒ stringread-only <src>signingKey.publicKey⇒ stringread-only The uncompressed public key.
This will always begin with the prefix 0x04 and be 132 characters long (the 0x prefix and 130 hexadecimal nibbles).
Creates a new SigningKey for privateKey.
Returns the ECDH shared secret between this private key and the other key.
The other key may be any type of key, a raw public key, a compressed/uncompressed pubic key or aprivate key.
Best practice is usually to use a cryptographic hash on the returned value before using it as a symetric secret.
sign1 = new SigningKey(id("some-secret-1"))
sign2 = new SigningKey(id("some-secret-2"))
sign1.computeSharedSecret(sign2.publicKey)
// '0x04b5bc2a5428042331a4c70da8f090d5552bdb35bc08a00ea8ed0a9b6d8737b8b7ea016b268d7cb9f02e11736b82b129ea3f37a8fdc6a7b0e9f5cdde4105ceb0de'
sign2.computeSharedSecret(sign1.publicKey)
// '0x04b5bc2a5428042331a4c70da8f090d5552bdb35bc08a00ea8ed0a9b6d8737b8b7ea016b268d7cb9f02e11736b82b129ea3f37a8fdc6a7b0e9f5cdde4105ceb0de'
Return the signature of the signed digest.
Returns the point resulting from adding the ellipic curve points p0 and p1.
This is not a common function most developers should require, but can be useful for certain privacy-specific techniques.
For example, it is used by HDNodeWallet to compute child addresses from parent public keys and chain codes.
<src>SigningKey.computePublicKey(key: BytesLike, compressed?: boolean)⇒ string Compute the public key for key, optionally compressed.
The key may be any type of key, a raw public key, a compressed/uncompressed public key or private key.
sign = new SigningKey(id("some-secret"));
SigningKey.computePublicKey(sign.privateKey)
// '0x04925bec9818e11ac806bf8b142a7965ac9231aaa9d23f256795d63b1d8d7f203f7481609b6a6964a0f5b459585e9d18a9ec9070d0baf24689138868811c974c96'
SigningKey.computePublicKey(sign.privateKey, true)
// '0x02925bec9818e11ac806bf8b142a7965ac9231aaa9d23f256795d63b1d8d7f203f'
SigningKey.computePublicKey(sign.publicKey, false);
// '0x04925bec9818e11ac806bf8b142a7965ac9231aaa9d23f256795d63b1d8d7f203f7481609b6a6964a0f5b459585e9d18a9ec9070d0baf24689138868811c974c96'
SigningKey.computePublicKey(sign.publicKey, true);
// '0x02925bec9818e11ac806bf8b142a7965ac9231aaa9d23f256795d63b1d8d7f203f'
Returns the public key for the private key which produced the signature for the given digest.
key = new SigningKey(id("some-secret"))
digest = id("hello world")
sig = key.sign(digest)
key.publicKey
// '0x04925bec9818e11ac806bf8b142a7965ac9231aaa9d23f256795d63b1d8d7f203f7481609b6a6964a0f5b459585e9d18a9ec9070d0baf24689138868811c974c96'
SigningKey.recoverPublicKey(digest, sig)
// '0x04925bec9818e11ac806bf8b142a7965ac9231aaa9d23f256795d63b1d8d7f203f7481609b6a6964a0f5b459585e9d18a9ec9070d0baf24689138868811c974c96'