jr can now make an account on aegora
This commit is contained in:
@@ -3,3 +3,5 @@
|
|||||||
erl_crash.dump
|
erl_crash.dump
|
||||||
*.beam
|
*.beam
|
||||||
__pycache__
|
__pycache__
|
||||||
|
jex_include
|
||||||
|
jex_mindist
|
||||||
|
|||||||
+5
-2
@@ -78,10 +78,13 @@
|
|||||||
|
|
||||||
<script src="./dist/jex_include/local-tweetnacl-1.0.3/dist/nacl.js"></script>
|
<script src="./dist/jex_include/local-tweetnacl-1.0.3/dist/nacl.js"></script>
|
||||||
|
|
||||||
|
<!-- same but for blakejs
|
||||||
|
<script src="./dist/jex_include/local-blakejs-1.2.1/dist/index.js"></script>
|
||||||
|
-->
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
this is a non-issue
|
this is a non-issue
|
||||||
-->
|
-->
|
||||||
<script type="module"
|
<script type="module" src="./dist/background.js"></script>
|
||||||
src="./dist/background.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+1
-1
@@ -4,6 +4,6 @@
|
|||||||
{version, "0.1.0"}.
|
{version, "0.1.0"}.
|
||||||
{deps, ["local-tweetnacl-1.0.3",
|
{deps, ["local-tweetnacl-1.0.3",
|
||||||
"local-awcp-0.2.2",
|
"local-awcp-0.2.2",
|
||||||
"local-vdk_aecrypt-0.1.0",
|
"local-blakejs-1.2.1",
|
||||||
"local-vdk_aeser-0.1.0",
|
"local-vdk_aeser-0.1.0",
|
||||||
"local-vdk_binary-0.1.0"]}.
|
"local-vdk_binary-0.1.0"]}.
|
||||||
|
|||||||
+223
-2
@@ -52,7 +52,8 @@
|
|||||||
|
|
||||||
|
|
||||||
import * as awcp from './jex_include/local-awcp-0.2.2/dist/awcp.js';
|
import * as awcp from './jex_include/local-awcp-0.2.2/dist/awcp.js';
|
||||||
import * as vdk_aecrypt from './jex_include/local-vdk_aecrypt-0.1.0/dist/vdk_aecrypt.js';
|
import * as blake2b from './jex_include/local-blakejs-1.2.1/dist/blake2b.js';
|
||||||
|
//import * as vdk_aecrypt from './jex_include/local-vdk_aecrypt-0.1.0/dist/vdk_aecrypt.js';
|
||||||
import * as vdk_aeser from './jex_include/local-vdk_aeser-0.1.0/dist/vdk_aeser.js';
|
import * as vdk_aeser from './jex_include/local-vdk_aeser-0.1.0/dist/vdk_aeser.js';
|
||||||
import * as vdk_binary from './jex_include/local-vdk_binary-0.1.0/dist/vdk_binary.js';
|
import * as vdk_binary from './jex_include/local-vdk_binary-0.1.0/dist/vdk_binary.js';
|
||||||
|
|
||||||
@@ -321,7 +322,7 @@ bi_msg_handler_content
|
|||||||
// use nacl detached signatures
|
// use nacl detached signatures
|
||||||
// https://github.com/aeternity/aepp-sdk-js/blob/5df22dd297abebc0607710793a7234e6761570d4/src/utils/crypto.ts#L141-L143
|
// https://github.com/aeternity/aepp-sdk-js/blob/5df22dd297abebc0607710793a7234e6761570d4/src/utils/crypto.ts#L141-L143
|
||||||
// https://github.com/aeternity/aepp-sdk-js/blob/5df22dd297abebc0607710793a7234e6761570d4/src/utils/crypto.ts#L160-L167
|
// https://github.com/aeternity/aepp-sdk-js/blob/5df22dd297abebc0607710793a7234e6761570d4/src/utils/crypto.ts#L160-L167
|
||||||
let hashed_salted_msg : Uint8Array = vdk_aecrypt.hash_and_salt_msg(msg_str);
|
let hashed_salted_msg : Uint8Array = hash_and_salt_msg(msg_str);
|
||||||
let signature : Uint8Array = nacl.sign.detached(hashed_salted_msg, secret_key);
|
let signature : Uint8Array = nacl.sign.detached(hashed_salted_msg, secret_key);
|
||||||
let signature_str : string = vdk_binary.bytes_to_hex_str(signature);
|
let signature_str : string = vdk_binary.bytes_to_hex_str(signature);
|
||||||
return w2a_ok({signature: signature_str});
|
return w2a_ok({signature: signature_str});
|
||||||
@@ -683,3 +684,223 @@ bi_s2i
|
|||||||
|
|
||||||
return {keypairs: i_keypairs};
|
return {keypairs: i_keypairs};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quoth https://github.com/aeternity/Vanillae/blob/f054744bbceb957afa8fbcf31d93055dd277396b/sidekick/src/sidekick.ts#L926-L1015
|
||||||
|
*
|
||||||
|
* > In order to exclude the possibility of someone using this functionality to
|
||||||
|
* > trick the user into signing a transaction, the wallet salts and hashes the
|
||||||
|
* > message, and *then* signs the salted/hashed message.
|
||||||
|
* >
|
||||||
|
* > Therefore, naively attempting to verify the signature will not work. You
|
||||||
|
* > must apply the same preprocessing steps as the wallet, **THEN** check the
|
||||||
|
* > signature against the salted/hashed message.
|
||||||
|
* >
|
||||||
|
* > ```erlang
|
||||||
|
* > -spec hashed_salted_msg(Message) -> HashedSaltedMessage
|
||||||
|
* > when Message :: binary(),
|
||||||
|
* > HashedSaltedMessage :: binary().
|
||||||
|
* > % @doc Salt the message then hash with blake2b. See:
|
||||||
|
* > % 1. https://github.com/aeternity/aepp-sdk-js/blob/370f1e30064ad0239ba59931908d9aba0a2e86b6/src/utils/crypto.ts#L83-L85
|
||||||
|
* > % 2. https://github.com/aeternity/eblake2/blob/60a079f00d72d1bfcc25de8e6996d28f912db3fd/src/eblake2.erl#L23-L25
|
||||||
|
* >
|
||||||
|
* > hashed_salted_msg(Msg) ->
|
||||||
|
* > {ok, HSMsg} = eblake2:blake2b(32, salted_msg(Msg)),
|
||||||
|
* > HSMsg.
|
||||||
|
* >
|
||||||
|
* >
|
||||||
|
* >
|
||||||
|
* > -spec salted_msg(Message) -> SaltedMessage
|
||||||
|
* > when Message :: binary(),
|
||||||
|
* > SaltedMessage :: binary().
|
||||||
|
* > % @doc Salt the message the way Superhero does before signing.
|
||||||
|
* > %
|
||||||
|
* > % See: https://github.com/aeternity/aepp-sdk-js/blob/370f1e30064ad0239ba59931908d9aba0a2e86b6/src/utils/crypto.ts#L171-L175
|
||||||
|
* >
|
||||||
|
* > salted_msg(Msg) when is_binary(Msg) ->
|
||||||
|
* > P = <<"aeternity Signed Message:\n">>,
|
||||||
|
* > {ok, SP} = btc_varuint_encode(byte_size(P)),
|
||||||
|
* > {ok, SMsg} = btc_varuint_encode(byte_size(Msg)),
|
||||||
|
* > <<SP/binary,
|
||||||
|
* > P/binary,
|
||||||
|
* > SMsg/binary,
|
||||||
|
* > Msg/binary>>.
|
||||||
|
* >
|
||||||
|
* >
|
||||||
|
* >
|
||||||
|
* > -spec btc_varuint_encode(Integer) -> Result
|
||||||
|
* > when Integer :: integer(),
|
||||||
|
* > Result :: {ok, Encoded :: binary()}
|
||||||
|
* > | {error, Reason :: term()}.
|
||||||
|
* > % @doc Bitcoin varuint encode
|
||||||
|
* > %
|
||||||
|
* > % See: https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
|
||||||
|
* >
|
||||||
|
* > btc_varuint_encode(N) when N < 0 ->
|
||||||
|
* > {error, {negative_N, N}};
|
||||||
|
* > btc_varuint_encode(N) when N < 16#FD ->
|
||||||
|
* > {ok, <<N>>};
|
||||||
|
* > btc_varuint_encode(N) when N =< 16#FFFF ->
|
||||||
|
* > NBytes = eu(N, 2),
|
||||||
|
* > {ok, <<16#FD, NBytes/binary>>};
|
||||||
|
* > btc_varuint_encode(N) when N =< 16#FFFF_FFFF ->
|
||||||
|
* > NBytes = eu(N, 4),
|
||||||
|
* > {ok, <<16#FE, NBytes/binary>>};
|
||||||
|
* > btc_varuint_encode(N) when N < (2 bsl 64) ->
|
||||||
|
* > NBytes = eu(N, 8),
|
||||||
|
* > {ok, <<16#FF, NBytes/binary>>}.
|
||||||
|
* >
|
||||||
|
* > % eu = encode unsigned (little endian with a given byte width)
|
||||||
|
* > % means add zero bytes to the end as needed
|
||||||
|
* > eu(N, Size) ->
|
||||||
|
* > Bytes = binary:encode_unsigned(N, little),
|
||||||
|
* > NExtraZeros = Size - byte_size(Bytes),
|
||||||
|
* > ExtraZeros = << <<0>> || _ <- lists:seq(1, NExtraZeros) >>,
|
||||||
|
* > <<Bytes/binary, ExtraZeros/binary>>.
|
||||||
|
* > ```
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
hash_and_salt_msg
|
||||||
|
(message_str : string)
|
||||||
|
: Uint8Array
|
||||||
|
{
|
||||||
|
let message_bytes : Uint8Array = vdk_binary.encode_utf8(message_str);
|
||||||
|
return blake2b.blake2b(salt_msg(message_bytes), // bytes to hash
|
||||||
|
undefined, // key (optional)
|
||||||
|
32); // resulting byte length
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* salt the message
|
||||||
|
*
|
||||||
|
* ```erlang
|
||||||
|
* -spec salted_msg(Message) -> SaltedMessage
|
||||||
|
* when Message :: binary(),
|
||||||
|
* SaltedMessage :: binary().
|
||||||
|
* % @doc Salt the message the way Superhero does before signing.
|
||||||
|
* %
|
||||||
|
* % See: https://github.com/aeternity/aepp-sdk-js/blob/370f1e30064ad0239ba59931908d9aba0a2e86b6/src/utils/crypto.ts#L171-L175
|
||||||
|
*
|
||||||
|
* salted_msg(Msg) when is_binary(Msg) ->
|
||||||
|
* P = <<"aeternity Signed Message:\n">>,
|
||||||
|
* {ok, SP} = btc_varuint_encode(byte_size(P)),
|
||||||
|
* {ok, SMsg} = btc_varuint_encode(byte_size(Msg)),
|
||||||
|
* <<SP/binary,
|
||||||
|
* P/binary,
|
||||||
|
* SMsg/binary,
|
||||||
|
* Msg/binary>>.
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
salt_msg
|
||||||
|
(msg_bytes : Uint8Array)
|
||||||
|
: Uint8Array
|
||||||
|
{
|
||||||
|
let prefix_str : string = 'aeternity Signed Message:\n';
|
||||||
|
let prefix_bytes : Uint8Array = vdk_binary.encode_utf8(prefix_str);
|
||||||
|
let prefix_size_n : number = prefix_bytes.byteLength;
|
||||||
|
let prefix_size_bytes : Uint8Array = btc_varuint_encode(prefix_size_n);
|
||||||
|
let msg_size_n : number = msg_bytes.byteLength;
|
||||||
|
let msg_size_bytes : Uint8Array = btc_varuint_encode(msg_size_n);
|
||||||
|
|
||||||
|
return vdk_binary.bytes_concat_arr([prefix_size_bytes,
|
||||||
|
prefix_bytes,
|
||||||
|
msg_size_bytes,
|
||||||
|
msg_bytes]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* btc varuint encoding
|
||||||
|
*
|
||||||
|
* function is the following Erlang code translated into TS
|
||||||
|
*
|
||||||
|
* ```erlang
|
||||||
|
* -spec btc_varuint_encode(Integer) -> Result
|
||||||
|
* when Integer :: integer(),
|
||||||
|
* Result :: {ok, Encoded :: binary()}
|
||||||
|
* | {error, Reason :: term()}.
|
||||||
|
* % @doc Bitcoin varuint encode
|
||||||
|
* %
|
||||||
|
* % See: https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
|
||||||
|
*
|
||||||
|
* btc_varuint_encode(N) when N < 0 ->
|
||||||
|
* {error, {negative_N, N}};
|
||||||
|
* btc_varuint_encode(N) when N < 16#FD ->
|
||||||
|
* {ok, <<N>>};
|
||||||
|
* btc_varuint_encode(N) when N =< 16#FFFF ->
|
||||||
|
* NBytes = eu(N, 2),
|
||||||
|
* {ok, <<16#FD, NBytes/binary>>};
|
||||||
|
* btc_varuint_encode(N) when N =< 16#FFFF_FFFF ->
|
||||||
|
* NBytes = eu(N, 4),
|
||||||
|
* {ok, <<16#FE, NBytes/binary>>};
|
||||||
|
* btc_varuint_encode(N) when N < (2 bsl 64) ->
|
||||||
|
* NBytes = eu(N, 8),
|
||||||
|
* {ok, <<16#FF, NBytes/binary>>}.
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
btc_varuint_encode
|
||||||
|
(n : number)
|
||||||
|
: Uint8Array
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(n < 0) {
|
||||||
|
throw new Error('n < 0');
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(n < 0xFD) {
|
||||||
|
return new Uint8Array([n]);
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(n < 0xFFFF) {
|
||||||
|
let prefix : Uint8Array = new Uint8Array([0xFD]);
|
||||||
|
let n_bytes : Uint8Array = eu(n, 2);
|
||||||
|
return vdk_binary.bytes_concat(prefix, n_bytes);
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(n < 0xFFFF_FFFF) {
|
||||||
|
let prefix : Uint8Array = new Uint8Array([0xFE]);
|
||||||
|
let n_bytes : Uint8Array = eu(n, 4);
|
||||||
|
return vdk_binary.bytes_concat(prefix, n_bytes);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let prefix : Uint8Array = new Uint8Array([0xFF]);
|
||||||
|
let n_bytes : Uint8Array = eu(n, 8);
|
||||||
|
return vdk_binary.bytes_concat(prefix, n_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unsigned integer little endian encoding with a given byte width
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
eu
|
||||||
|
(n : number,
|
||||||
|
byte_width : number)
|
||||||
|
: Uint8Array
|
||||||
|
{
|
||||||
|
// endianness is byte-level not bit-level
|
||||||
|
// 3> binary:encode_unsigned(258, big).
|
||||||
|
// <<1,2>>
|
||||||
|
// 4> binary:encode_unsigned(258, little).
|
||||||
|
// <<2,1>>
|
||||||
|
|
||||||
|
// first encode n as little endian
|
||||||
|
let n_bytes : Uint8Array = vdk_binary.bigint_to_bytes_little(BigInt(n));
|
||||||
|
// figure out how much padding we need
|
||||||
|
let num_extra_zeros : number = byte_width - n_bytes.byteLength;
|
||||||
|
let extra_zeros : Uint8Array = vdk_binary.bytes_zeros(num_extra_zeros);
|
||||||
|
|
||||||
|
// in little endian, padding 0s go on the right
|
||||||
|
return vdk_binary.bytes_concat(n_bytes, extra_zeros);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
// Adapted from the reference implementation in RFC7693
|
// Adapted from the reference implementation in RFC7693
|
||||||
// Ported to Javascript by DC - https://github.com/dcposch
|
// Ported to Javascript by DC - https://github.com/dcposch
|
||||||
|
|
||||||
const util = require('./util')
|
// const util = require('./util')
|
||||||
|
import * as util from './util.js';
|
||||||
|
|
||||||
// 64-bit unsigned addition
|
// 64-bit unsigned addition
|
||||||
// Sets v[a,a+1] += v[b,b+1]
|
// Sets v[a,a+1] += v[b,b+1]
|
||||||
@@ -356,10 +357,10 @@ function blake2bHex (input, key, outlen, salt, personal) {
|
|||||||
return util.toHex(output)
|
return util.toHex(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
export {
|
||||||
blake2b: blake2b,
|
blake2b,
|
||||||
blake2bHex: blake2bHex,
|
blake2bHex,
|
||||||
blake2bInit: blake2bInit,
|
blake2bInit,
|
||||||
blake2bUpdate: blake2bUpdate,
|
blake2bUpdate,
|
||||||
blake2bFinal: blake2bFinal
|
blake2bFinal
|
||||||
}
|
}
|
||||||
Vendored
-812
File diff suppressed because one or more lines are too long
+5
-5
@@ -76,9 +76,9 @@ function testSpeed (hashFn, N, M) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
export {
|
||||||
normalizeInput: normalizeInput,
|
normalizeInput,
|
||||||
toHex: toHex,
|
toHex,
|
||||||
debugPrint: debugPrint,
|
debugPrint,
|
||||||
testSpeed: testSpeed
|
testSpeed
|
||||||
}
|
}
|
||||||
-812
File diff suppressed because one or more lines are too long
Vendored
-96
@@ -1,96 +0,0 @@
|
|||||||
export interface Blake2bCTX {
|
|
||||||
b: Uint8Array;
|
|
||||||
h: Uint32Array;
|
|
||||||
t: number;
|
|
||||||
c: number;
|
|
||||||
outlen: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Blake2b hashing context
|
|
||||||
* @param outlen between 1 and 64
|
|
||||||
* @param key optional
|
|
||||||
* @returns the hashing context
|
|
||||||
*/
|
|
||||||
export declare function blake2bInit(outlen?: number, key?: Uint8Array): Blake2bCTX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a Blake2b streaming hash
|
|
||||||
* @param ctx hashing context from blake2bInit()
|
|
||||||
* @param input Byte array
|
|
||||||
*/
|
|
||||||
export declare function blake2bUpdate(ctx: Blake2bCTX, input: ArrayLike<number>): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Completes a Blake2b streaming hash
|
|
||||||
* @param ctx hashing context from blake2bInit()
|
|
||||||
* @returns the final hash
|
|
||||||
*/
|
|
||||||
export declare function blake2bFinal(ctx: Blake2bCTX): Uint8Array;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param input the input bytes, as a string, Buffer, or Uint8Array
|
|
||||||
* @param key optional key Uint8Array, up to 64 bytes
|
|
||||||
* @param outlen optional output length in bytes, defaults to 64
|
|
||||||
* @returns an n-byte Uint8Array
|
|
||||||
*/
|
|
||||||
export declare function blake2b(input: string | Uint8Array, key?: Uint8Array, outlen?: number): Uint8Array;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the Blake2b hash of a string or byte array
|
|
||||||
*
|
|
||||||
* @param input the input bytes, as a string, Buffer, or Uint8Array
|
|
||||||
* @param key optional key Uint8Array, up to 64 bytes
|
|
||||||
* @param outlen outlen - optional output length in bytes, defaults to 64
|
|
||||||
* @returns an n-byte hash in hex, all lowercase
|
|
||||||
*/
|
|
||||||
export declare function blake2bHex(input: string | Uint8Array, key?: Uint8Array, outlen?: number): string;
|
|
||||||
|
|
||||||
export interface Blake2sCTX {
|
|
||||||
h: Uint32Array;
|
|
||||||
b: Uint8Array;
|
|
||||||
c: number;
|
|
||||||
t: number;
|
|
||||||
outlen: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Blake2s hashing context
|
|
||||||
* @param outlen between 1 and 32
|
|
||||||
* @param key optional Uint8Array key
|
|
||||||
* @returns the hashing context
|
|
||||||
*/
|
|
||||||
export declare function blake2sInit(outlen: number, key?: Uint8Array): Blake2sCTX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a Blake2s streaming hash
|
|
||||||
* @param ctx hashing context from blake2sinit()
|
|
||||||
* @param input byte array
|
|
||||||
*/
|
|
||||||
export declare function blake2sUpdate(ctx: Blake2sCTX, input: ArrayLike<number>): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Completes a Blake2s streaming hash
|
|
||||||
* @param ctx hashing context from blake2sinit()
|
|
||||||
* @returns Uint8Array containing the message digest
|
|
||||||
*/
|
|
||||||
export declare function blake2sFinal(ctx: Blake2sCTX): Uint8Array;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the Blake2s hash of a string or byte array, and returns a Uint8Array
|
|
||||||
* @param input the input bytes, as a string, Buffer, or Uint8Array
|
|
||||||
* @param key optional key Uint8Array, up to 32 bytes
|
|
||||||
* @param outlen optional output length in bytes, defaults to 64
|
|
||||||
* @returns an n-byte Uint8Array
|
|
||||||
*/
|
|
||||||
export declare function blake2s(input: string | Uint8Array, key?: Uint8Array, outlen?: number): Uint8Array;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param input the input bytes, as a string, Buffer, or Uint8Array
|
|
||||||
* @param key optional key Uint8Array, up to 32 bytes
|
|
||||||
* @param outlen optional output length in bytes, defaults to 64
|
|
||||||
* @returns an n-byte hash in hex, all lowercase
|
|
||||||
*/
|
|
||||||
export declare function blake2sHex(input: string | Uint8Array, key?: Uint8Array, outlen?: number): string;
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
const b2b = require('./blake2b')
|
|
||||||
const b2s = require('./blake2s')
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
blake2b: b2b.blake2b,
|
|
||||||
blake2bHex: b2b.blake2bHex,
|
|
||||||
blake2bInit: b2b.blake2bInit,
|
|
||||||
blake2bUpdate: b2b.blake2bUpdate,
|
|
||||||
blake2bFinal: b2b.blake2bFinal,
|
|
||||||
blake2s: b2s.blake2s,
|
|
||||||
blake2sHex: b2s.blake2sHex,
|
|
||||||
blake2sInit: b2s.blake2sInit,
|
|
||||||
blake2sUpdate: b2s.blake2sUpdate,
|
|
||||||
blake2sFinal: b2s.blake2sFinal
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user