import {assert, evaluateTestResults, init, runTest} from './utils.js';
// Test SHA-256 against test vectors function testSha256() { // Test vectors taken from https://www.di-mgt.com.au/sha_testvectors.html const testVectors = [
{
data: '',
expected: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
},
{
data: 'abc',
expected: 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad',
},
{
data: 'a'.repeat(1_000_000),
expected: 'cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0',
},
];
for (const testVector of testVectors) { const computed = Buffer.from(
sha256(Buffer.from(testVector.data, 'utf8')),
).toString('hex');
assert(
testVector.expected === computed,
`Computed SHA-256 should match expected one. Input: ${testVector.data}`,
);
}
}
// Test HMAC-SHA-256 against test vectors function testHmacSha256() { // Test vectors taken from https://datatracker.ietf.org/doc/html/rfc4231#section-4 const testVectors = [
{
key: '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b',
data: 'Hi There',
expected: 'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7',
},
{
key: '4a656665',
data: 'what do ya want for nothing?',
expected: '5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843',
},
{
key: 'a'.repeat(262),
data: 'Test Using Larger Than Block-Size Key - Hash Key First',
expected: '60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54',
},
];
for (const testVector of testVectors) { const computed = Buffer.from(
hmacSha256(
Buffer.from(testVector.key, 'hex'),
Buffer.from(testVector.data, 'utf8'),
),
).toString('hex');
assert(
testVector.expected === computed,
`Computed HMAC-SHA-256 should match expected one. Input: ${testVector.data}, Key: ${testVector.key}`,
);
}
}
for (const testVector of testVectors) { const key =
testVector.key === undefined
? undefined
: Buffer.from(testVector.key, 'utf8'); const salt =
testVector.salt === undefined
? undefined
: Buffer.from(testVector.salt, 'hex'); const personal =
testVector.personal === undefined
? undefined
: Buffer.from(testVector.personal, 'hex'); const data =
testVector.data === undefined
? new Uint8Array(0)
: Buffer.from(testVector.data, 'utf8');
for (const [outputLength, blake2b] of outputLengths) { const computed = Buffer.from(
blake2b(
key,
personal ?? new Uint8Array(0),
salt ?? new Uint8Array(0),
data,
),
).toString('hex');
// Dispatch to the correct function call depending on the existance of // salt and personal const expected = blake2bReference(
outputLength,
key,
salt,
personal, true,
)
.update(data)
.digest('hex');
assert(
expected === computed,
`Computed Blake2b with output length ${outputLength} should match expected one. Key: ${testVector.key}, Salt: ${testVector.salt}, Personal: ${testVector.personal}, Data: ${testVector.data}`,
);
}
}
}
// Test XSalsa20Poly1305 by encrypting/decrypting between libthreema and TweetNacl function testXSalsa20Poly1305() { // Compute Keys // Alice uses libthreema const aliceSecretKey = Buffer.from('aa'.repeat(32), 'hex'); const alicePublicKey = x25519DerivePublicKey(aliceSecretKey);
// Derive shared keys between Alice and Bob const sharedKeyAliceBob = x25519HSalsa20DeriveSharedSecret(
bobPublicKey,
aliceSecretKey,
); const sharedKeyBobAlice = tweetNaCl.box.before(
alicePublicKey,
bobSecretKey,
);
// Encrypt from Alice to Bob const nonceAliceBob = Buffer.from('01'.repeat(24), 'hex'); const messageAliceBob = 'Hi Bob'; const encryptedMessageAliceBob = xSalsa20Poly1305Encrypt(
sharedKeyAliceBob,
nonceAliceBob,
Buffer.from(messageAliceBob, 'utf8'),
[],
);
// Decrypt const decryptedMessageAliceBob = Buffer.from(
tweetNaCl.box.open.after(
encryptedMessageAliceBob,
nonceAliceBob,
sharedKeyBobAlice,
),
).toString('utf8'); assert(
decryptedMessageAliceBob === messageAliceBob, 'Decrypted message from Alice to Bob does not match original one',
);
// Encrypt from Bob to Alice const nonceBobAlice = Buffer.from('02'.repeat(24), 'hex'); const messageBobAlice = 'Hi Alice from Bob'; const encryptedMessageBobAlice = tweetNaCl.box.after(
Buffer.from(messageBobAlice, 'utf8'),
nonceBobAlice,
sharedKeyBobAlice,
);
// Decrypt const decryptedMessageBobAlice = Buffer.from(
xSalsa20Poly1305Decrypt(
sharedKeyAliceBob,
nonceBobAlice,
encryptedMessageBobAlice,
),
).toString('utf8'); assert(
decryptedMessageBobAlice === messageBobAlice, 'Decrypted message from Bob to Alice does not match original one',
);
}
async function testXChaCha20Poly1305() {
await _sodium.ready; const sodium = _sodium;
// Derive shared keys between Alice and Bob const sharedKeyAliceBob = x25519HSalsa20DeriveSharedSecret(
bobPublicKey,
aliceSecretKey,
); const sharedKeyBobAlice = sodium.crypto_box_beforenm(
alicePublicKey,
bobSecretKey,
); assert(
Buffer.from(sharedKeyAliceBob).toString('hex') ===
Buffer.from(sharedKeyBobAlice).toString('hex'), 'Derived Keys do not match.',
);
// Encrypt from Alice to Bob const nonceAliceBob = Buffer.from('01'.repeat(24, 'hex')); const messageAliceBob = 'Hi Bob'; const encryptedMessageAliceBob = xChaCha20Poly1305Encrypt(
sharedKeyAliceBob,
nonceAliceBob,
Buffer.from(messageAliceBob, 'utf8'),
[],
);
// Decrypt const decryptedMessageAliceBob = Buffer.from(
sodium.crypto_aead_xchacha20poly1305_ietf_decrypt( null,
encryptedMessageAliceBob, null,
nonceAliceBob,
sharedKeyBobAlice,
),
).toString('utf8'); assert(
decryptedMessageAliceBob === messageAliceBob, 'Decrypted message from Alice to Bob does not match original one',
);
// Encrypt from Bob to Alice const nonceBobAlice = Buffer.from('02'.repeat(24, 'hex')); const messageBobAlice = 'Hi Alice from Bob'; const encryptedMessageBobAlice =
sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(
Buffer.from(messageBobAlice, 'utf8'), null, null,
nonceBobAlice,
sharedKeyBobAlice,
);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.